% \iffalse meta-comment
%
% Copyright (C) 2007-2013 by Christoph Bersch <usenet@bersch.net>
%
% This work may be distributed and/or modified under the
% 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.3c or later is part of all distributions of LaTeX
% version 2008/05/04 or later.
% \fi
%
% \iffalse
%<*driver>
\ProvidesFile{pst-optexp.dtx}
%</driver>
%<stylefile>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<stylefile>\ProvidesPackage{pst-optexp}
%<*stylefile>
    [2013/03/20 v3.6 Optical experimental setups with PSTricks]
%</stylefile>
%
%<*driver>
\documentclass[a4paper, DIV=9, oneside, toc=index, parskip=half-]{scrreprt}
\usepackage{doc}
\setcounter{IndexColumns}{2}
\usepackage[utf8]{inputenc} 
\usepackage[T1]{fontenc}
\usepackage{lmodern} 
\usepackage{amsmath, marvosym} 
\usepackage{bera}
\providecommand*\mainlang{}
\usepackage[ngerman, english,\mainlang]{babel}
\usepackage{prettyref}
\usepackage[dvipsnames,x11names,svgnames]{xcolor}
\usepackage{array,booktabs,paralist,tabularx}
\usepackage{ragged2e, calc}
\newlength{\POEcaptionmargin}
\newlength{\POEcaptionheight}
\usepackage[labelfont={color=DOrange}, 
            singlelinecheck=false, 
            justification=raggedright]{caption} 
\DeclareCaptionFormat{poenocaption}{%
  \setlength{\POEcaptionmargin}{\widthof{#1}+7pt}%
  \setlength{\POEcaptionheight}{\heightof{#1}+3pt}%
  \hspace*{-\POEcaptionmargin}#1\par\vspace*{-\POEcaptionheight}%
}%
\DeclareCaptionFormat{poecaption}{%
  \setlength{\POEcaptionmargin}{\widthof{#1}+7pt}%
  \hspace*{-\POEcaptionmargin}#1#2#3\par
}%
\captionsetup[lstlisting]{format=poenocaption}
\usepackage{nicefrac}
\usepackage{pst-func}
\usepackage{pst-optexp}
\usepackage{pst-circ}
\usepackage[makeindex]{splitidx}
\usepackage{hypdoc}
\hypersetup{%
  colorlinks=true, 
  urlcolor=DOrange, 
  linkcolor=pdflinkcolor, 
  breaklinks,
  linktocpage=true} 
\usepackage{breakurl}
\definecolor{DOrange}{rgb}{1,.4,.2}%
\definecolor{DDOrange}{rgb}{0.7, 0.23, 0.07}%
\colorlet{pdflinkcolor}{DOrange}
\colorlet{DGreen}{green!90!black}
\usepackage{pst-tree}
\usepackage{showexpl}
\makeatletter\renewcommand*\SX@Info{}\makeatother
\usepackage{etoolbox}
\undef{\cs}\undef{\cmd}
\usepackage{ltxdockit}
\newcommand{\poeTR}[1]{\TR{\ttfamily\color{DOrange}#1}}
\definecolor{colKeys}{rgb}{0,0,0}
\definecolor{colIdentifier}{rgb}{0,0,0}
\colorlet{colComments}{green!60!black}
\definecolor{colString}{rgb}{0,0.5,0}
\newlength{\codeoverhang}
\setlength{\codeoverhang}{0.5\marginparwidth+\marginparsep}
\lstset{%
  language=[LaTeX]TeX, identifierstyle=\color{colIdentifier}, %
  keywordstyle=\color{colKeys}, %
  keywordstyle = [21]\color{DOrange}, %
  keywordstyle = [22]\color{DOrange}, %
  stringstyle=\color{colString}, %
  commentstyle=\color{colComments}, %
  float=hbp,%
  basicstyle=\ttfamily\small, %
  columns=flexible, %
  tabsize=4, %
  showspaces=false, %
  showstringspaces=false, %
  breaklines=true, %
  breakautoindent=true, %
  breakatwhitespace=true, %
  captionpos=t, %
  belowcaptionskip=0pt,%
  abovecaptionskip=0pt,%
  xleftmargin=1em, %
  prebreak = {\raisebox{-0.5ex}[\ht\strutbox]{\kern0.5ex\large\Righttorque}},
  rulecolor=\color{black!20}, %
  texcsstyle = [20]\color{DDOrange},%!60!black},%{red!60!black}, %
  moretexcs = [20]{lens, optbox, oenode, oenodeIn, oenodeExt, oenodeOut,
    oenodeRefA, oenodeRefB, oenodeTrefA, oenodeTrefB, oenodeLabel, oenodeRotref,
    oenodeBeam, oenodeBeamUp, oenodeBeamLow, oenodeCenter, oenodeIfc, 
    oeBeamVec, oeBeamVecUp, oeBeamVecLow,
    optplate, optretplate, pinhole, crystal,optdetector, optdiode,
    doveprism, glanthompson, polarization, mirror, beamsplitter,
    optgrating, optprism, rightangleprism, pentaprism, optdipole,
    optripole, optfiber, optamp, optmzm, optfilter, polcontrol,
    optisolator, optswitch, fiberdelayline, optfiberpolarizer,
    fibercollimator, optcoupler, wdmcoupler, wdmsplitter, optcirculator,
    fiberbox, drawbeam, drawwidebeam, drawfiber, frontlayer, backlayer,
    newOptexpDipole, newOptexpTripole, newOptexpFiberDipole,optplane}, %
  explpreset={%
    pos=l, width=-99pt, hsep=5mm, overhang=\codeoverhang, varwidth,
    vsep=\bigskipamount, rframe={}}, extendedchars=true
}%
\lstdefinestyle{example}{explpreset={%
    escapechar=*, pos=l, width=-99pt, hsep=5mm, overhang=\codeoverhang,
    varwidth, vsep=\bigskipamount, rframe={}}}
\makeatletter
\providecommand\ON{%
  \gdef\lst@alloverstyle##1{\textcolor{black!50}{\strut##1}%
}}
\providecommand\OFF{\xdef\lst@alloverstyle##1{##1}}
\makeatother
\colorlet{sectioncolor}{DOrange}
\addtokomafont{sectioning}{\color{sectioncolor}}
\usepackage[automark,nouppercase]{scrpage2}
\pagestyle{scrheadings}
\clearscrheadings
\clearscrplain
\ohead{\pagemark}
\ihead{\headmark}
\ofoot[\pagemark]{}
\automark[subsection]{section}
\setheadsepline{.4pt}[\color{DOrange}]
\setheadwidth[0pt]{text}
\setfootwidth[0pt]{text}
\makeatletter
\patchcmd{\l@chapter}{1.5em}{2em}{}{}
\renewcommand*\l@section{\bprot@dottedtocline{1}{1.5em}{3.0em}}
\renewcommand*\l@subsection{\bprot@dottedtocline{2}{3.8em}{4.0em}}
\newrobustcmd*{\fnurl}[1][]{\hyper@normalise\ltd@fnurl{#1}}
\def\ltd@fnurl#1#2{\footnote{#1\hyper@linkurl{\Hurl{#2}}{#2}}}
\newrobustcmd*{\arxivurl}[1]{\href{http://arxiv.org/abs/#1}{arXiv:#1}}
\newrobustcmd*{\doiurl}[1]{\href{http://dx.doi.org/#1}{DOI:#1}}
\makeatother
\usepackage{csquotes}
\MakeAutoQuote{«}{»}
%^^A spot is used in ltxdockit.sty
\colorlet{spot}{sectioncolor}
\newpsstyle{Refline}{linecolor=gray!70}
\newpsstyle{CenterNode}{linecolor=blue, dotstyle=x, dotscale=1.5}
\psset[optexp]{usefiberstyle}
\colorlet{Refline}{gray!70}
%^^A Fonts definitions used in ltxdockit.sty
\renewcommand*{\verbatimfont}{\ttfamily}
\renewcommand*{\displayverbfont}{\ttfamily}
\renewcommand*{\marglistfont}{\spotcolor\sffamily\small}
\renewcommand*{\margnotefont}{\sffamily\small}
\renewcommand*{\optionlistfont}{\spotcolor\sffamily\displayverbfont}
\renewcommand*{\ltxsyntaxfont}{\ttfamily}
\renewcommand*{\ltxsyntaxlabelfont}{\spotcolor\displayverbfont}
\renewcommand*{\changelogfont}{\normalfont}
\renewcommand*{\changeloglabelfont}{\spotcolor\sffamily\bfseries}

\makeatletter
%^^A an idea from GL to provide links inside the listings to the pst-optexp commands: 
%^^A <https://groups.google.com/groups/search?as_umsgid=4d89ee49%240%2418590%24426a74cc%40news.free.fr>
\providerobustcmd*\ifrefundefined [1]{%
  \begingroup%
    \csname @safe@activestrue\endcsname%
    \expandafter\endgroup\csname @\ifcsname r@#1\endcsname second\else first\fi oftwo\endcsname
}% \ifrefundefined
\def\lsthk@OutputBox@H@@k{%
    \begingroup%
      \let\lst@UM\@empty%
      \edef\@tempc{cmd:\detokenize\expandafter{\the\lst@token }}%\edef
      \ifrefundefined{\@tempc}%
    \endgroup%
    \sethyperlistings%
}% \lsthk@OutputBox@H@@k
\def\sethyperlistings {\global\let \hyperlistingsreference =\@tempc
     \endgroup \aftergroup \dohyperlistings }% after \hbox
\def\dohyperlistings {\def\lst@alloverstyle ##1{\hyperlistings ##1}}
\def\hyperlistings{%
    \setbox\@tempboxa\hbox%
    \bgroup%
      \rlap{\hypersetup {linkcolor=.}\relax\fboxrule\z@%
      \hyperref[\hyperlistingsreference]{\boxframe{\wd\@tempboxa}{\ht\@tempboxa}{\dp\@tempboxa}}}%
      \unhbox\@tempboxa%
    \egroup%
}% \hyperlistings
\let\lsthk@OutputBox\lsthk@OutputBox@H@@k

\newenvironment*{stylelist}
  {\list{}{%
     \setlength{\labelwidth}{\marglistwidth}%
     \setlength{\labelsep}{0.5\marglistsep}%
     \setlength{\leftmargin}{0pt}%
     \renewcommand*{\makelabel}[1]{\hss\optionlistfont##1}}%
     \let\styleitem\POE@styleitem}%
  {\endlist}

\def\ltd@optionlist{%
  \let\optitem\POE@optitem
  \let\valitem\POE@valitem
  \let\choitem\POE@choitem
  \let\boolitem\POE@boolitem
  \let\intitem\POE@intitem
  \let\numitem\POE@numitem
  \let\psnumitem\POE@psnumitem
  \let\poeitem\ltd@item
  \let\styleitem\POE@styleitem}

\def\POE@styleitem{%
  \@ifnextchar[%]
    {\POE@styleitem@i}
    {\POE@styleitem@i[]}
}
\def\POE@styleitem@i[#1]#2{%
  \item[{#2}]%
  \label{prm:#2}%
  \begingroup\raggedright
  \prm{psstyle}%
  \settowidth\@tempdimb{\prm{psstyle}}%
  \settowidth\@tempdimc{#2}%
  \@tempdimc=\dimexpr\@tempdimc+\labelsep-\labelwidth\relax
  \ifdim\@tempdimc>0pt%
    \@tempdima=\dimexpr\linewidth-\@tempdimb-\@tempdimc\relax
  \else
    \@tempdima=\dimexpr\linewidth-\@tempdimb\relax
  \fi
  \ifblank{#1}
    {}
    {\parbox[t]{\@tempdima}{\raggedleft default:~\ltd@textverb{#1}}}%
  \par\endgroup}

\def\POE@optitem{%
  \@ifstar
    {\boolfalse{@tempswa}\POE@optitem@i}
    {\booltrue{@tempswa}\POE@optitem@i}}
\newcommand*{\POE@optitem@i}[3][]{%
  \ifbool{@tempswa}{\label{prm:#2}}{}%
  \xLkeyword{#2}%
  \ifblank{#1}
    {\ltd@option{#2}{#2}{#3}{}}
    {\ltd@option{#2}{#2}{#3}{\ltd@textverb{#1}}}}%

\def\POE@valitem{%
  \@ifstar
    {\boolfalse{@tempswa}\POE@valitem@i}
    {\booltrue{@tempswa}\POE@valitem@i}}
\newcommand*{\POE@valitem@i}[3][]{%
  \ifbool{@tempswa}{\label{prm:#2}}{}%
  \xLkeyword{#2}%
  \ifblank{#1}
    {\ltd@option{#2}{#2}{\prm{#3}}{}}
    {\ltd@option{#2}{#2}{\prm{#3}}{\ltd@textverb{#1}}}}%

\def\POE@choitem{%
  \@ifstar
    {\boolfalse{@tempswa}\POE@choitem@i}
    {\booltrue{@tempswa}\POE@choitem@i}}
\newcommand*{\POE@choitem@i}[3][]{%
  \ifbool{@tempswa}{\label{prm:#2}}{}%
  \xLkeyword{#2}%
  \ifblank{#1}
    {\ltd@option{#2}{#2}{\ltd@verblist{#3}}{}}
    {\ltd@option{#2}{#2}{\ltd@verblist{#3}}{\ltd@textverb{#1}}}}%

\def\POE@boolitem{%
  \@ifstar
    {\boolfalse{@tempswa}\POE@boolitem@i}
    {\booltrue{@tempswa}\POE@boolitem@i}}
\newcommand*{\POE@boolitem@i}[2][]{%
  \ifbool{@tempswa}{\label{prm:#2}}{}%
  \xLkeyword{#2}%
  \ifblank{#1}
    {\ltd@option{#2}{#2}{\ltd@verblist{true,false}}{}}
    {\ltd@option{#2}{#2}{\ltd@verblist{true,false}}{\ltd@textverb{#1}}}}%

\def\POE@intitem{%
  \@ifstar
    {\boolfalse{@tempswa}\POE@intitem@i}
    {\booltrue{@tempswa}\POE@intitem@i}}
\newcommand*{\POE@intitem@i}[2][]{%
  \ifbool{@tempswa}{\label{prm:#2}}{}%
  \xLkeyword{#2}%
  \ifblank{#1}
    {\ltd@option{#2}{#2}{\prm{int}}{}}
    {\ltd@option{#2}{#2}{\prm{int}}{\ltd@textverb{#1}}}}%

\def\POE@numitem{%
  \@ifstar
    {\boolfalse{@tempswa}\POE@numitem@i}
    {\booltrue{@tempswa}\POE@numitem@i}}
\newcommand*{\POE@numitem@i}[2][]{%
  \ifbool{@tempswa}{\label{prm:#2}}{}%
  \xLkeyword{#2}%
  \ifblank{#1}
    {\ltd@option{#2}{#2}{\prm{num}}{}}
    {\ltd@option{#2}{#2}{\prm{num}}{\ltd@textverb{#1}}}}%

\def\POE@psnumitem{%
  \@ifstar
    {\boolfalse{@tempswa}\POE@psnumitem@i}
    {\booltrue{@tempswa}\POE@psnumitem@i}}
\newcommand*{\POE@psnumitem@i}[2][]{%
  \ifbool{@tempswa}{\label{prm:#2}}{}%
  \xLkeyword{#2}%
  \ifblank{#1}
    {\ltd@option{#2}{#2}{\prm{psnum}}{}}
    {\ltd@option{#2}{#2}{\prm{psnum}}{\ltd@textverb{#1}}}}%

\def\ltd@cmditem@ii#1#2{%
  \ltd@itemsave
  \ifhmode
    \itemsep-\topsep
  \else
    \ltd@itembreak
  \fi
  \item[#1]%
  \ltd@itemrest
  \ifblank{#2}{}{\label{cmd:#2}}%
  \begingroup
  \ltd@syntaxsetup
  \ltxsyntaxfont
  \let\@tempa\@empty
  \ltd@parseargs}


\let\plainllap\llap
\newrobustcmd\macro@llap[1]{{\global\let\llap\plainllap
 \setbox0=\hbox\bgroup \macro@font\small\saved@macroname\egroup
 \ifdim\wd0>30mm
    \hbox to\z@ \bgroup\hss \hbox to30mm{\unhcopy0\hss}\egroup
    \edef\@tempa{\hskip\dimexpr\the\wd0-30mm}\global\everypar\expandafter{\the\expandafter\everypar
                                                                           \@tempa \global\everypar{}}%
 \else \llap{\unhbox0}\fi}}
 \AtBeginEnvironment{macro}{\let\llap\macro@llap}
\makeatother

\newcommand*{\PSstring}[1]{{\normalfont\small\ttfamily(#1)}}
\newcommand*{\PSarray}[1]{{\normalfont\small\ttfamily[#1]}}
\newcommand*{\PSname}[1]{{\normalfont\small\ttfamily/#1}}
\newcommand*{\PSproc}[1]{{\normalfont\small\ttfamily\textbraceleft #1\textbraceright}}
\newcommand*{\PSvar}[1]{{\normalfont\small\ttfamily #1}}
\newcommand*{\PSop}[1]{{\normalfont\small\ttfamily\color{DOrange}\hskip 3pt #1\hskip 3pt}}

\newcommand*{\nodename}[1]{\emph{#1}}
\newcommand*{\param}[1]{\normalfont\texttt{#1}}
\newcommand*{\paramvalue}[1]{\texttt{#1}}
\newcommand*{\styleshape}[1]{\texttt{#1}}
\newcommand{\docindex}[1]{\sindex[doc]{#1|hyperpage}}
\makeatletter
\def\Lcs{\@ifstar{\Lcs@nobm}{\Lcs@bm}}
\def\Lcs@nobm#1{\nxLcs{#1}\xLcs{#1}}
\def\Lcs@bm#1{\hyperref[cmd:#1]{\Lcs@nobm{#1}}}
\def\xLcs#1{\docindex{#1=\nxLcs{#1}}\docindex{\POEindexMacro!#1=\nxLcs{#1}}}
\def\nxLcs#1{\texttt{\textbackslash#1}}

\def\LPack#1{\texttt{#1}\docindex{#1=\texttt{#1}}\docindex{\POEindexPackage!#1=\texttt{#1}}}
\def\nxLPack#1{\texttt{#1}}

\def\Lenv{\@ifstar{\Lenv@nobm}{\Lenv@bm}}
\def\Lenv@nobm#1{\nxLenv{#1}\xLenv{#1}}
\def\Lenv@bm#1{\hyperref[env:#1]{\Lenv@nobm{#1}}}
\def\xLenv#1{\docindex{#1=\texttt{#1}}\docindex{\POEindexEnv!#1=\texttt{#1}}}
\def\nxLenv#1{\texttt{#1}}
\let\orig@ltd@envitem\ltd@envitem
\def\ltd@envitem#1{\orig@ltd@envitem{#1}\label{env:#1}\xLenv{#1}}

\def\Lkeyword{\@ifstar{\Lkeyword@nobm}{\Lkeyword@bm}}
\def\Lkeyword@nobm#1{\texttt{#1}\xLkeyword{#1}}
\def\Lkeyword@bm#1{\hyperref[prm:#1]{\Lkeyword@nobm{#1}}}
\def\xLkeyword#1{\docindex{#1=\texttt{#1}}\docindex{\POEindexKeyword!#1=\texttt{#1}}}
\def\nxLkeyword#1{\texttt{#1}}

\def\xLoption#1{\docindex{#1=\texttt{#1}}\docindex{\POEindexOption!#1=\texttt{#1}}}
\def\Loption#1{\texttt{#1}\xLoption{#1}}
\def\nxLoption#1{\texttt{#1}}

\def\Lstyle{\@ifstar{\Lstyle@nobm}{\Lstyle@bm}}
\def\Lstyle@nobm#1{\texttt{#1}\xLstyle{#1}}
\def\Lstyle@bm#1{\hyperref[prm:#1]{\Lstyle@nobm{#1}}}
\def\xLstyle#1{\docindex{#1=\texttt{#1}}\docindex{\POEindexStyle!#1=\texttt{#1}}}
\def\nxLstyle#1{\texttt{#1}}

\def\Ldipole#1{\nxLcs{#1}\xLdipole{#1}}
\def\xLdipole#1{\docindex{#1=\nxLcs{#1}}\docindex{\POEindexDipoles!#1=\nxLcs{#1}}}

\def\Ltripole#1{\nxLcs{#1}\xLtripole{#1}}
\def\xLtripole#1{\docindex{#1=\nxLcs{#1}}\docindex{\POEindexTripoles!#1=\nxLcs{#1}}}

\def\Lfdipole#1{\nxLcs{#1}\xLfdipole{#1}}
\def\xLfdipole#1{\docindex{#1=\nxLcs{#1}}\docindex{\POEindexFiberDipoles!#1=\nxLcs{#1}}}

\def\Lfmultipole#1{\nxLcs{#1}\xLfmultipole{#1}}
\def\xLfmultipole#1{\docindex{#1=\nxLcs{#1}}\docindex{\POEindexFiberMultipoles!#1=\nxLcs{#1}}}
\makeatother

\newcommand{\dipoledesc}[1]{%
  \xLdipole{#1}%
  \cmditem{#1}[options](in)(out){label}%
}
\newcommand{\tripoledesc}[1]{%
  \xLtripole{#1}%
  \cmditem{#1}[options](in)(center)(out){label}%
}

\newcommand{\fiberdipoledesc}[1]{%
  \xLfdipole{#1}%
  \cmditem{#1}[options](in)(out){label}%
}

\newenvironment*{pssyntax}
  {\list{}{\small
     \setlength{\labelsep}{0pt}%
     \setlength{\leftmargin}{10pt}%
     \item[]}}
  {\endlist}

\newcommand{\psarglistfont}{\small}
\newenvironment*{psarglist}
  {\list{}{%
     \setlength{\labelwidth}{10pt}%
     \setlength{\labelsep}{0pt}%
     \setlength{\leftmargin}{0pt}%
     \setlength{\itemsep}{\parsep}%
     \setlength{\parsep}{0pt}%
     \renewcommand*{\makelabel}[1]{\hss\psarglistfont##1}}}
  {\endlist}

\makeatletter
\renewenvironment{theglossary}{\GlossaryParms \let\item\@idxitem \ignorespaces}{}
\makeatother
\def\psargitem#1{\item[#1]\hfill\par\nobreak}

\addtopsstyle{Fiber}{linecolor=DOrange,linewidth=1.5\pslinewidth}
\addtopsstyle{Beam}{linewidth=1.5\pslinewidth}
\EnableCrossrefs
\CodelineIndex
\OnlyDescription
\begin{document}
  \DocInput{pst-optexp.dtx}
\end{document}
%</driver>
% \fi
%
% \CheckSum{0}
%
% \CharacterTable
%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}
%
% \GetFileInfo{pst-optexp.dtx}
%
% \DoNotIndex{\@,\g@addto@macro,\newif,\gdef,\xdef,\newcounter,\or,\ifcase,\\}
% \DoNotIndex{\newcommand,\newenvironment,\def,\edef,\let,\if,\ifx,\else,\fi,\@ifnextchar}
% \DoNotIndex{\space,\relax,\nr,\val,\ignorespaces,\ifdim,\ifcat,\@nil,\@none,\@empty}
% \DoNotIndex{\PackageError,\PackageWarning,\advance,\csname,\endcsname,\bgroup,\egroup}
% \DoNotIndex{\expandafter,\POE@comp,\@postcode}
% \DoNotIndex{\psset}
% \DoNotIndex{\@wd,\@sz,\@ht,\@yshift,\@step,\@xl,\@sep,\@r,\@dp,\@altan,\@extpostcode}
% \DoNotIndex{\@f@cnt,\@f@r,\@f@sep,\@hshift,\@bs@wd,\@c@caxisL,\@cnt,\@pstfalse,\@psttrue}
% \DoNotIndex{\@th,\@rL,\@rR,\i,\long,\optexp@nodeA,\optexp@nodeB}
% \DoNotIndex{\POE@temp,\POE@tempa,\POE@tempb,\POE@tempc,\POE@tempd}
% \DoNotIndex{\POE@getref@b,\POE@getref@c,\POE@getref@l,\POE@getref@r,\POE@getref@t}
% \DoNotIndex{\the,\toks@}
% 
% \newif\ifGERMAN  \GERMANfalse
% \newif\ifENGLISH \ENGLISHfalse
% \iflanguage{ngerman}{\GERMANtrue}{%
%   \iflanguage{german}{\GERMANtrue}{\GERMANfalse}}
% \iflanguage{english}{\ENGLISHtrue}{\ENGLISHfalse}
%
% \ifGERMAN
%   \newrefformat{chap}{Kap.~\ref{#1}}
%   \newrefformat{sec}{Kap.~\ref{#1}}
%   \newrefformat{l}{Zeile~\ref{#1}}
%   \newrefformat{ex}{Bsp.~\ref{#1}}
%   \newrefformat{tab}{Tab.~\ref{#1}}
%   \newrefformat{fig}{Abb.~\ref{#1}}
%   \newindex[Quelltextindex]{idx}
%   \newindex[Dokumentationsindex]{doc}
%   \newcommand{\POEindexPackage}{Paket}
%   \newcommand{\POEindexMacro}{Makro}
%   \newcommand{\POEindexKeyword}{Schlüsselwort}
%   \newcommand{\POEindexEnv}{Umgebung}
%   \newcommand{\POEindexOption}{Option}
%   \newcommand{\POEindexStyle}{Stil}
%   \newcommand{\POEindexDipoles}{Zweipol}
%   \newcommand{\POEindexTripoles}{Dreipol}
%   \newcommand{\POEindexFiberDipoles}{Faserzweipol}
%   \newcommand{\POEindexFiberMultipoles}{Fasermultipol}
%   \renewcommand*\lstlistingname{Bsp.}
% \fi
% \ifENGLISH
%   \newrefformat{chap}{Sec.~\ref{#1}}
%   \newrefformat{sec}{Sec.~\ref{#1}} 
%   \newrefformat{l}{Line~\ref{#1}}
%   \newrefformat{ex}{Ex.~\ref{#1}}
%   \newrefformat{tab}{Tab.~\ref{#1}}
%   \newrefformat{fig}{Fig.~\ref{#1}}
%   \newindex[Code index]{idx}
%   \newindex[Documentation index]{doc}
%   \newcommand{\POEindexPackage}{Package}
%   \newcommand{\POEindexMacro}{Macro}
%   \newcommand{\POEindexKeyword}{Keyword}
%   \newcommand{\POEindexEnv}{Environment}
%   \newcommand{\POEindexOption}{Option} 
%   \newcommand{\POEindexStyle}{Style}
%   \newcommand{\POEindexDipoles}{Dipoles}
%   \newcommand{\POEindexTripoles}{Tripoles}
%   \newcommand{\POEindexFiberDipoles}{Fiber dipoles}
%   \newcommand{\POEindexFiberMultipoles}{Fiber multipoles}
%   \renewcommand*\lstlistingname{Ex.}
% \fi
%
% \newcommand{\refpointexplanation}{%
%   \ifGERMAN
%   Analog zum Referenzpunkt von \nxLcs{rput}, kann jede Kombination von
%   \opt{c} (mittig), \opt{t} (oben), \opt{b} (unten), \opt{l} (links) und
%   \opt{r} (rechts) sein.
%   \fi
%   \ifENGLISH
%   Like the reference point of \nxLcs{rput}, can be any comination of
%   \opt{c} (center), \opt{t} (top), \opt{b} (bottom), \opt{l} (left), and
%   \opt{r} (right).
%   \fi}
%
% \newcommand*{\linewidthexplanation}[2]{% 
% \ifGERMAN
% Die Linienbreite #1. Diese könnte ebenfalls über den
% \opt{linewidth} Parameter gesetzt werden. Mit diesem Parameter kann
% aber die Linienbreite aller #2 global eingestellt werden.
% \fi
% \ifENGLISH
% The linewidth of the #1. This could be defined also with the
% generic \opt{linewidth} option. But this parameter allows setting
% globally the linewidth of all #2.
% \fi
% }
%
% \newcommand*{\deprecatedmsg}[2][3.0]{%
% \ifGERMAN Dieser Parameter ist seit Version #1 veraltet, verwenden Sie stattdessen #2. \fi
% \ifENGLISH This parameter is deprecated since version #1, use #2 instead.\fi
% }
%
% \newcommand*{\addtostylemsg}[1]{%
% \ifGERMAN Der vorhandene \Lstyle{#1}-Stil wird lokal um die Parameter in
%   \prm{list} erweitert, \prm{list} muss mit geschweiften Klammern gekapselt
%   werden.
% \fi
% \ifENGLISH 
%   The \Lstyle{#1} style is extended by locally adding the
%   parameters contained in \prm{list}. The \prm{list} must be surrounded
%   by curly braces.
% \fi
% }
% \newcommand*{\newstylemsg}[1]{%
% \ifGERMAN Ähnlich wie \Lkeyword{addto#1}, nur wird der
%   \Lstyle{#1}-Stil mit den neuen Parametern überschrieben.
% \fi
% \ifENGLISH Similar to \Lkeyword{addto#1}, but an existing
%   \Lstyle{#1} style is overwritten with the new parameter set.
% \fi
% }
%
% \makeatletter
% \renewcommand\maketitle{^^A
% \thispagestyle{empty}^^A
% \begin{titlepage}
% \begin{pspicture}(1.6in,0.685in)(10,21.7)
%   \psframe[fillstyle=solid,linecolor=lightgray,fillcolor=lightgray,linestyle=solid](0,-5.75)(21.5,10)
%   \psframe[fillstyle=solid,linecolor=Orange!85!Red,fillcolor=Orange!85!Red,linestyle=solid](0,10)(21.5,10.5)
%   \psframe[fillstyle=solid,linecolor=Orange!85!Red,fillcolor=Orange!85!Red,linestyle=solid](0,21.1)(21.5,21.2)
%   \rput[lb](3,22){\Huge\sffamily\color{Orange!65!Red}\psscalebox{2}{\textbf{PSTricks}}}
%   \rput[lb](3,14.1){\parbox{15cm}{\sffamily\RaggedRight\bfseries\huge\@title}}
%   \rput[lb](3,7.6){\parbox{13cm}{\sffamily\@date}}
%   \rput[lb](3,-2.6){\parbox[b]{17cm}{\sffamily\RaggedRight 
%     ~\hfill\makebox[7cm][l]{\ifGERMAN Paketautor:\fi\ifENGLISH Package author:\fi}\\
%     ~\hfill\makebox[7cm][l]{^^A
%       \bfseries\tabular[t]{@{}l@{}}\@author\endtabular}}}
%  \rput[C](11,4){\bgImage}
%  \end{pspicture}^^A
% \end{titlepage}}
% \makeatother
% 
% \ifGERMAN
%   \title{\texttt{pst-optexp}\\ Optische Versuchsaufbauten\\[0.5ex] \small \fileversion}
%   \hypersetup{pdftitle={Optische Versuchsaufbauten}}
% \fi
% \ifENGLISH
%   \title{\texttt{pst-optexp}\\ Drawing optical experimental setups\\[0.5ex] \small \fileversion}
%   \hypersetup{pdftitle={Optical experimental setups}}
% \fi
% \author{Christoph Bersch}
% \date{\filedate}
% \def\bgImage{\psset{unit=1.3}
% \begin{pspicture}(-0.2,0.1)(8.2,5.3)
%   \pnode(0,3){M1}
%   \pnode(8,3){M2}
%   \pnode(8,0.5){In}
%   \pnode(6.5,0.5){Min}
%   \pnode(6.5,3){Pin}
%   \pnode(4.5,3){Min2}
%   \pnode(1.3, 0.5){Mout}
%   \pnode(1.3,3){Pout}
%   \pnode(3.5,3){Mout2}
%   \pnode(0,0.5){Out}
%   \definecolor[ps]{bl}{rgb}{tx@addDict begin Red Green Blue end}
%   \addtopsstyle{Beam}{linecolor=bl, linejoin=1}
%   \psset{mirrortype=extended, mirrordepth=0.15}
%   \newpsstyle{ExtendedMirror}{linestyle=none, hatchwidth=0.5\pslinewidth, hatchsep=1.2\pslinewidth,
%                 fillstyle=hlines}
%   \begin{optexp}
%   \mirror[mirrorwidth=4, mirrorradius=11.](M2)(M1)(M2)
%   \mirror[mirrorwidth=4, mirrorradius=10.4](M1)(M2)(M1)
%   \mirror(In)(Min)(Pin)
%   \optprism[n=1.85, addtoOptComp={linewidth=1.5\pslinewidth}](Min)(Pin)(Min2)
%   \mirror[compshift=-0.4](Pin)(Min2)(Pin)
%   \mirror[compshift=0.4](Pout)(Mout2)(Pout)
%   \optprism[n=1.85, linewidth=1.5\pslinewidth](Mout2)(Pout)(Mout)
%   \mirror(Pout)(Mout)(Out)
%   \multido{\i=0+1}{40}{^^A
%     \pstVerb{^^A
%       \i\space 650 400 sub 39 div mul 400 add 
%       tx@addDict begin wavelengthToRGB end }^^A
%     \drawbeam[n={-0.002 \i\space mul n add}](In){3-5}{2}{1}{6-7}
%   }^^A
%   \newpsstyle{Beam}{linecolor=red}
%   \backlayer{\psline[style=Beam,ArrowInside=->, linewidth=2\pslinewidth, arrowinset=0](In)(\oenodeIn{3})(\oenodeOut{4})}
%   \drawbeam[linewidth=2\pslinewidth, arrows=->, arrowinset=0, loadbeampoints, beaminsidefirst, n=1.9325]{7-8}(Out)  
% \end{optexp}
% \rput(4,4.5){^^A
%   \psframe[fillstyle=solid,fillcolor=gray!70](-0.1, -0.6)(0.1, 0.7)
%   \multido{\r=-0.5+0.1}{12}{^^A
%     \psline[linewidth=0.5\pslinewidth](-0.1,\r)(0.1,\r)
%   }^^A
% }
% \end{pspicture}}
%
% \maketitle
% 
% \clearpage
% \tableofcontents
% \clearpage
% 
% \ifGERMAN
%   \chapter{Einführung}
% \fi
% \ifENGLISH
%   \chapter{Introduction}
% \fi
% 
% \ifGERMAN
%   \section{Über das Paket}
%
%   \LPack{pst-optexp} ist ein PSTricks-Paket zum Skizzieren optischer
%   Versuchsaufbauten. Dafür werden viele unterschiedliche Freistrahl- und
%   Faserkomponenten bereitgestellt, deren Ausrichtung, Positionierung und
%   Beschriftung einfach und flexibel eingestellt werden kann. Die Komponenten
%   können dann mit Fasern oder Lichtstrahlen verbunden werden, wobei auch
%   realistische Strahlengänge mit Raytracing möglich sind.
% \fi 
% \ifENGLISH
%   \section{About the package}
%   The package \LPack{pst-optexp} is a collection of optical components that
%   facilitate easy sketching of optical experimental setups. A lot of different
%   free-ray and fiber components are provided, which alignment, positioning and
%   labelling can be achieved in very simple and flexible ways. The components
%   can be connected with fibers or beams, realistic raytraced beam paths are
%   also possible.
% \fi
%
% \ifGERMAN
%   \section{Anforderungen}
%   \LPack{pst-optexp} benötigt \LaTeX{} und aktuelle Versionen der
%   Pakete \LPack{pst-node}, \LPack{pstricks-add}, \LPack{multido},
%   \LPack{pst-eucl} und \LPack{environ}.
%
%   Alle PSTricks-Pakete machen regen Gebrauch von der Postscript-Sprache, so
%   dass der typische Arbeitsfluss \opt{latex}, \opt{dvips} und
%   ggf. \opt{ps2pdf} umfasst. Es gibt viele alternative Methoden um die
%   Dokumente zu
%   kompilieren.\fnurl{http://tug.org/PSTricks/main.cgi?file=pdf/pdfoutput}
% \fi
% \ifENGLISH
%   \section{Requirements}
%   \LPack{pst-optexp} requires \LaTeX{} and recent versions of
%   \LPack{pst-node}, \LPack{multido}, \LPack{pstricks-add},
%   \LPack{pst-eucl}, and \LPack{environ}. 
%
%   All PSTricks package rely heavily on the Postscript language so that the
%   typical workflow involves \opt{latex}, \opt{dvips}, and \opt{ps2pdf}. Of
%   course there are several alternative ways to compile your
%   documents.\fnurl{http://tug.org/PSTricks/main.cgi?file=pdf/pdfoutput} 
% \fi
%
% \ifGERMAN
%   \section{Verbreitung und Installation}
%   Dieses Paket ist auf
%   CTAN\fnurl{http://mirror.ctan.org/help/Catalogue/entries/pst-optexp.html}
%   erhältlich und in \TeX Live and MiK\TeX{} enthalten.
% 
%   Das \LPack{pst-optexp}-Paket umfasst die zwei Hauptdateien
%   \texttt{pst-optexp.ins} und \texttt{pst-optexp.dtx}. Durch Aufrufen
%   von \texttt{tex pst-optexp.ins} werden die beiden folgenden
%   Dateien erzeugt:
%   \begin{itemize}
%   \item \texttt{pst-optexp.pro}: die Postscript Prologdatei
%   \item \texttt{pst-optexp.sty}: die \LaTeX{} Stildatei
%   \end{itemize}
%   Speichern Sie diese Dateien in einem Verzeichnis der Teil Ihres
%   lokalen \TeX-Baums ist.
% 
%   Vergessen Sie nicht \texttt{texhash} aufzurufen um den Baum zu
%   aktualisieren. MiK\TeX{}-Benutzer müssen die Dateinamen-Datenbank
%   (FNDB) aktualisieren.
% 
%   Detailliertere Information finden Sie in der Dokumentation Ihrer
%   \LaTeX-Distribution über die Installation in den lokalen
%   \TeX{}-Baum.
% \fi
% \ifENGLISH
%   \section{Distribution and installation}
%   This package is available on
%   CTAN\fnurl{http://mirror.ctan.org/help/Catalogue/entries/pst-optexp.html} and
%   is included in \TeX Live and MiK\TeX.
% 
%   The \LPack{pst-optexp} package consists of the two main files
%   \texttt{pst-optexp.ins} and \texttt{pst-optexp.dtx}. By running \texttt{tex
%   pst-optexp.ins} the following derived files are generated:
%   \begin{itemize}
%   \item \texttt{pst-optexp.pro}: the Postscript prolog file
%   \item \texttt{pst-optexp.sty}: the \LaTeX{} style file
%   \end{itemize}
%   Save the files in a directory which is part of your local \TeX{} tree.
% 
%   Do not forget to run \texttt{texhash} to update this tree. For MiK\TeX{}
%   users, do not forget to update the file name database (FNDB).
% 
%   For more detailed information see the documentation of your personal
%   \LaTeX{} distribution on installing packages to your local \TeX{}
%   system.
% \fi
%
% \ifGERMAN\section{Lizenz}\fi
% \ifENGLISH\section{License}\fi
% \ifGERMAN
% Es wird die Erlaubnis gewährt, dieses Dokument zu kopieren, zu verteilen
% und\slash oder zu modifizieren, unter den Bestimmungen der \LaTeX{} Project
% Public License, Version
% 1.3c.\fnurl{http://www.latex-project.org/lppl.txt}. Dieses
% Paket wird vom Autor betreut (author-maintained).
% \fi
% \ifENGLISH
% Permission is granted
% to copy, distribute and\slash or modify this software under the terms of the
% \LaTeX{} Project Public License, version
% 1.3c.\fnurl{http://www.latex-project.org/lppl.txt} This
% package is author-maintained.
% \fi
%
% \ifGERMAN
%   \section{Abwärtskompatibilität}
% \fi
% \ifENGLISH
%   \section{Backward compatibility}
% \fi 
% \ifGERMAN In Version 3.0 wurde dem Paket erheblich fortgeschrittenere
%   Funktionalität hinzugefügt, die es zu schwierig machte zur
%   Vorgängerversion 2.1 vollständig abwärtskompatibel zu
%   bleiben. Insbesondere war die Funktionsweise des \Lcs{drawbeam}
%   Makros grundlegend falsch konzipiert, so dass ein Wechsel zur neuen
%   Funktionalität so schnell wie möglich erfolgen sollte.
%
%   Eine genauere Zusammenstellung der nicht-kompatiblen Änderungen und Hinweise
%   zur Migration von älteren Dokumenten finden Sie in \prettyref{sec:bwd-comp}.
% \fi
% \ifENGLISH
% Version 3.0 introduced a lot of advanced features which made it too difficult
% to maintain full backward compatibility with version 2.1. Especially the
% \Lcs{drawbeam} macro was broken by design, so that it was best to drop the old
% flaw as early as possible.
%
% You find a more detailled list of changes and information for migration of old
% documents in \prettyref{sec:bwd-comp}.
% \fi
%
% \section{Notation}\label{sec:notation}
% \ifGERMAN
% Die meisten Parametertypen, die im Laufe des Dokuments verwendet werden, sind
% selbsterklärend, andere bedürfen einer genaueren Erläuterung (z.B. der
% Unterschied zwischen \prm{num} und \prm{psnum}). \prettyref{tab:paramref}
% erklärt die geläufigsten Typen.
% \fi
% \ifENGLISH
% Often the parameter types are self-explanatory, but in some cases a clear
% distinction is needed, e.g. between \prm{num} and
% \prm{psnum}. \prettyref{tab:paramref} explains some commonly used types.
% \fi
%
% \begin{table}\centering
% \begin{tabularx}{0.9\linewidth}{>{\itshape}lX} \toprule
%   Name & \ifENGLISH description\fi\ifGERMAN Beschreibung\fi\\ \midrule
%   num & \ifENGLISH float number\fi\ifGERMAN Gleitkommazahl\fi \\ 
%   psnum & \ifENGLISH Postscript code which evaluates to a number\fi
%           \ifGERMAN Postscript-Kode der zu einer Zahl auswertet\fi\\
%   int & \ifENGLISH integer number\fi\ifGERMAN Ganzzahl\fi\\ 
%   dimen & \ifENGLISH dimension\fi\ifGERMAN Länge\fi\\
%   psstyle & \ifENGLISH custom graphics parameter configuration defined with \Lcs*{newpsstyle}\fi
%             \ifGERMAN Benutzerdefinierte Parameterkonfiguration definiert mit \Lcs*{newpsstyle}\fi\\
%   refpoint & \refpointexplanation\\ \bottomrule
% \end{tabularx}
% \ifGERMAN
% \caption{Parametertypen die in den Parameterdefinitionen verwendet werden.}
% \fi
% \ifENGLISH
% \caption{Parameter types used in the parameter reference.}
% \fi
% \label{tab:paramref}
% \end{table}
% 
% \ifGERMAN
%   \section{Danksagung}
% \fi
% \ifENGLISH
%   \section{Acknowledgements}
% \fi
% \ifGERMAN
% Ich danke allen Aktiven auf der PSTricks-Mailingliste für ihre Hilfe,
% insbesondere Herbert Voß. Mein Dank gilt ebenfalls unterschiedlichen
% Paketautoren, von denen ich Code kopiert und viel gelernt habe: Florent
% Chervet, Rolf Niepraschk und Heiko Oberdiek. Christine Römer hat mich mit
% ihrem Artikel in der DTK\footnote{Pakete in Deutsch dokumentieren. in Die
% TeXnische Komödie. Heft 2/2011, S. 28-35.} überzeugt, ebenfalls eine deutsche
% Dokumentation bereitzustellen. Der Dokumentationsstil ist eine Mischung aus
% der \opt{pst-doc} Klasse (Herbert Voß) und dem \opt{ltxdockit} Paket für die
% \opt{biblatex} Dokumentation (Philipp Lehmann).
% \fi
% \ifENGLISH
% I thank all the people of the PSTricks mailinglist for the continuous help,
% especially Herbert Voß. Thanks also to various package authors from which I
% learned and adopted code for this package, Florent Chervet, Rolf Niepraschk
% and Heiko Oberdiek. Christine Römer convinced me with her article in the
% german DTK\footnote{Pakete in Deutsch dokumentieren. in Die TeXnische
% Komödie. Heft 2/2011, S. 28-35.} to provide a german translation of the
% documentation. The documentation style is a mixture of the \opt{pst-doc} class
% (Herbert Voß) and the \opt{ltxdockit} package for the \opt{biblatex}
% documentation (Philipp Lehman).
% \fi
%
% \ifGERMAN
% \chapter{Grundlegende Ideen}
% \fi
% \ifENGLISH
%   \chapter{Basic ideas}
% \fi\label{chap:basics}
%
% \ifGERMAN Dieses Kapitel zeigt die grundlegenden Ideen und Konzepte, die in
% diesem Paket stecken. Anhand von elementaren Beispielen werden die
% Grundfunktionen wie Ausrichtung, Positionierung (\ref{sec:intro-comp}) und
% Beschriftung (\ref{sec:intro-label}) von Komponenten beschrieben. Anschließen
% wird deren Verbindung mit Strahlen (\ref{sec:intro-beam}) oder Fasern
% (\ref{sec:intro-fiber}) vorgestellt. 
%
% In \prettyref{sec:step-by-step} wird Schritt für Schritt die angedachte
% Vorgehensweise für das Erstellen von umfassenden Experimentskizzen
% erläutert. Eine vollständige Referenz aller Makros und deren Parameter finden
% Sie in \prettyref{chap:generalparam}--\ref{chap:custom}.
%
% Ein Versuchsaufbau besteht aus Komponenten, die anhand ihrer Referenzknoten
% positioniert, verschoben und gedreht werden können und optional eine
% Beschriftung erhalten. Anschließen werden die Komponenten mit Lichtstrahlen
% oder Fasern verbunden.
% \fi
% \ifENGLISH
% This chapter shows the basic ideas and concepts of this package. Starting with
% simple examples, basic functionality such as alignment, positioning
% (\ref{sec:intro-comp}) and labelling (\ref{sec:intro-label}) of components is
% presented. Following, the connection of components with beam rays
% (\ref{sec:intro-beam}) or fiber (\ref{sec:intro-fiber}) is demonstrated.
%
% In \prettyref{sec:step-by-step} several propositions for preparing large
% experimental sketches are illustrated step by step. For a complete reference
% of all macros and their parameters, see
% \prettyref{chap:generalparam}--\ref{chap:custom}.
%
% A drawing consists of components, which can be positioned, shifted and rotated
% based on their reference nodes, and may have an optional label. Then, the
% components are connected with beam rays or fibers.
% \fi
%
% \ifGERMAN\section{Die Komponenten}\fi
% \ifENGLISH\section{The components}\fi
% \label{sec:intro-comp}
%
% \ifGERMAN Eine Komponente wird anhand der Knoten, die bei ihrere Definition
% angegeben werden -- den Referenzknoten -- platziert. Im folgenden Beispiel
% wird eine Linse mittig auf die Verbindungslinie zwischen den Knoten
% \prm{A} und \prm{B} gesetzt: 
% \fi
% \ifENGLISH
% A component is positioned according to the nodes which are used for its
% definition---the reference nodes. In the following examples, the lens is
% placed centered between nodes \prm{A} and \prm{B}:
% \fi
%\iffalse
%<*ignore>
%\fi
\begin{LTXexample}[linerange={1-3,6-6}]
\begin{pspicture}[showgrid](0,-0.3)(3,2.3)
  \pnode(0,1){A}\pnode(3,1){B}
  \lens(A)(B)
  \psset{style=Refline}\color{Refline}
  \psdot(A)\uput[90](A){A}\psdot(B)\uput[90](B){B}
\end{pspicture}
\end{LTXexample}
%\iffalse
%</ignore>
%\fi 
%
% \ifGERMAN
% Diese Positionierung kann anhand von unterschiedlichen Parametern, wie
% z.B. \Lkeyword{abspos} beinflusst werden (siehe dazu
% \prettyref{sec:positioning} und \prettyref{sec:rotshift}). Im
% folgenden Beispiel wird die Linse \opt{0.5} Einheiten vom Knoten
% \prm{A} entfernt platziert, die Box sitzt am Ende der Referenzlinie
% $\overline{AB}$.
% \fi
% \ifENGLISH
% This position can be changed with a number of parameters, such as
% \Lkeyword{abspos} (see \prettyref{sec:positioning} and
% \prettyref{sec:rotshift}). In the next example, the lens is positioned
% \opt{0.5} units apart from node \prm{A}, the box is placed at the end
% of the reference line $\overline{AB}$.
% \fi
%\iffalse
%<*ignore>
%\fi
\begin{LTXexample}[morekeywords={[21]{abspos, position}}, linerange={1-4,7-7}]
\begin{pspicture}[showgrid](0,-0.3)(3,2.3)
  \pnode(0,1){A}\pnode(1.5,1){B}
  \lens[abspos=0.5](A)(B)
  \optbox[position=end](A)(B)
  \psset{style=Refline}\color{Refline}
  \psdot(A)\uput[90](A){A}\psdot(B)\uput[135](B){B}
\end{pspicture}
\end{LTXexample}
%\iffalse
%</ignore>
%\fi 
%
% \ifGERMAN Die Komponenten lassen sich allgemein in zwei Kategorien
% unterteilen: Faser- und Freistrahlkomponenten. Diese unterscheiden sich in
% erster Linie bezüglich ihrer Verbindungsmöglichkeiten: Freistrahlkomponenten
% können sowohl mit Lichtstrahlen als auch mit Fasern verbunden werden,
% wohingegen Faserkomponenten nur Faserverbindungen erlauben.
% \fi
% \ifENGLISH
% The components can be divided in two categories: free-ray and fiber
% components. These differ only in their connection possibilities: Free-ray
% components can have fiber or free-ray connections, whereas fiber components
% support fiber connections only.
% \fi
%
% \ifGERMAN\section{Beschriftungen}\fi
% \ifENGLISH\section{Labels}\fi
% \label{sec:intro-label}
%
% \ifGERMAN Jede Komponente kann optional eine Beschriftung erhalten, die
% relativ zur Komponente platziert wird.
% \fi
% \ifENGLISH Every component can have an optional label, which is positioned
% relative to the component.
% \fi
%\iffalse
%<*ignore>
%\fi
\begin{LTXexample}[morekeywords={[21]{labelangle, labelref, labeloffset}}, linerange={1-5,8-8}]
\begin{pspicture}[showgrid](0,-0.3)(3,3.3)
  \pnode(0,2.5){A}\pnode(2,2.5){B}\pnode(2,1.5){C}
  \mirror[labelangle=-45](A)(B)(C){M}
  \optbox[position=start, labeloffset=0, labelref=relative](C)(B){box}
  \drawbeam(A){1}{2}
  \psset{style=Refline}\color{Refline}
  \psdot(A)\uput[90](A){A}\psdot(B)\uput[-135](B){B}\psdot(C)\uput[45](C){C}
\end{pspicture}
\end{LTXexample}
%\iffalse
%</ignore>
%\fi 
%
% \ifGERMAN\section{Freistrahl-Verbindungen}\fi
% \ifENGLISH\section{Free-ray connections}\fi
% \label{sec:intro-beam}
%
% \ifGERMAN
% Freistrahlkomponenten können mit Lichtstrahlen verbunden werden, deren Weg mit
% Raytracing berechnet werden kann. Da es sich um ein Paket zum
% \emph{Skizzieren} experimenteller Aufbauten handelt, werden hier trotz der
% realistischen Berechnungen viele Möglichkeiten offen gehalten den Strahlengang
% zu manipulieren.
%
% Im einfachsten Fall wird eine einzelne Linie gezeichnet, deren optischer Weg
% über den Brechungsindex \Lkeyword{n} und das Snelliussche Brechungsgesetz
% bestimmt wird.
%
% Das Beispiel zeigt zwei Strahlen, die mit unterschiedlichen Anfangsbedingungen
% auf die Linse treffen, der rote Strahl startet mit einem Abstand von \opt{0.2}
% von der optischen Achse (\Lkeyword{beampos}) und wird entsprechend von der
% Linse abgelenkt.
% \fi
% \ifENGLISH
% Free-ray components can be connected with beam rays, which path can be
% calculated by raytracing. Besides the realistic tracing possibilities, there
% are many ways to manipulate the beam paths because you are dealing with a
% package for \emph{sketching} experimental setups.
%
% In the simplest case a single line is drawn, which optical path is determined
% by the refractive index \Lkeyword{n} and Snell's law.
%
% The example shows two beams which hit the lens with different initial
% conditions. The red beam starts at a distance of \opt{0.2} from the optical
% axis (\Lkeyword{beampos}) and is deflected by the lens accordingly.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-5,8-8}]
\begin{pspicture}[showgrid](0,-0.3)(3,2.3)
  \pnode(0,1){A}\pnode(3,1){B}
  \lens[n=2, lensradius=2 2, lensheight=1.5](A)(B)
  \drawbeam(A){1}(B)
  \drawbeam[beampos=0.4, linecolor=red](A){1}(B)
  \psset{style=Refline}\color{Refline}
  \psdot(A)\uput[-90](A){A}\psdot(B)\uput[90](B){B}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN Die Strahlen können mit beliebigen Strichlierungen und Pfeilen
% dekoriert werden.
% \fi
% \ifENGLISH The beams can be decorated with arbitrary dashs and arrows.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-4,7-7}]
\begin{pspicture}[showgrid](0,-0.3)(3,2.3)
  \pnode(0,1){A}\pnode(3,1){B}
  \lens[n=2, lens=2 2 1.5](A)(B)
  \drawbeam[beamangle=10, ArrowInside=->, arrows=-|, beaminside=false](A){1}(B)
  \psset{style=Refline}\color{Refline}
  \psdot(A)\uput[90](A){A}\psdot(B)\uput[-90](B){B}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN Ebenfalls können ausgedehnte Strahlen gezeichnet werden deren
% Randstrahlen mit \Lkeyword*{linestyle} etc. und deren Füllung über
% \Lkeyword*{fillstyle} geändert werden können.
% \fi
% \ifENGLISH You can also draw wide beams. The marginal rays can be changed with
% \Lkeyword*{linestyle} etc. and the filling with \Lkeyword*{fillstyle} etc.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-5,8-8}]
\begin{pspicture}[showgrid](0,-0.3)(3,2.3)
  \pnode(0.5,1){A}\pnode(3,1){B}
  \optbox[position=start, optboxsize=0.5 1](A)(B)
  \lens[n=2](A)(B)
  \drawwidebeam[beamwidth=0.2, fillstyle=solid, fillcolor=green!40]{1-2}(B)
  \psset{style=Refline}\color{Refline}
  \psdot(A)\uput[45](A){A}\psdot(B)\uput[135](B){B}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN Die Strahlen können auch hinter die Komponenten gelegt werden. Dafür
% müssen alle beteiligten Komponenten und Strahlen in eine
% \Lenv{optexp}-Umgebung gepackt werden (vergleiche das folgende Beispiel mit
% dem vorangegangenen).
% \fi
% \ifENGLISH The beams can also lay behind the components. For this you must
% enclose all respective components and rays in a \Lenv{optexp} environment
% (compare the previous example with the following one).
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}[showgrid](0,-0.3)(3,2.3)
  \pnode(1.5,1){A}\pnode(3,1){B}
  \begin{optexp}
    \optbox[position=start](A)(B)
    \lens[n=2](A)(B)
    \drawwidebeam[beamwidth=0.2, fillstyle=solid, fillcolor=green!40]{1}{2}(B)
  \end{optexp}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN\section{Faserverbindungen}\fi
% \ifENGLISH\section{Fiber connections}\fi
% \label{sec:intro-fiber}
%
% \ifGERMAN
% Eine andere Möglichkeit, Komponenten zu verbinden, sind Fasern
% (\Lcs{drawfiber}). Hiermit bestehen weitreichende Möglichkeiten die Fasern
% automatisch an die Komponentenausrichtung anzupassen.
% \fi
% \ifENGLISH
% Fibers (\Lcs{drawfiber}) are another possibility of connecting
% components. Here, you have several way of automatically adapting the fiber
% connection to the component alignment.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}[showgrid](0,-0.3)(3,3.3)
  \pnode(1,2.5){A}\pnode(2.5,1){B}
  \psset{optboxsize=1 0.6}
  \optbox[position=start](A)(B|A)
  \optbox[position=end](B|A)(B)
  \drawfiber{1}{2}
  \drawfiber[linecolor=blue, ncurv=1.2]{1}{2}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN Üblicherweise werden Fasern mit einer \Lcs*{nccurve}-Verbindung
% gezeichnet, jede andere Knotenverbindung ist aber ebenfalls möglich
% (\Lkeyword{fiberstyle}).
% \fi
% \ifENGLISH Usually, the fibers are drawn as \Lcs*{nccurve} connections, other
% node connections are possible as well (\Lkeyword{fiberstyle}).
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}[showgrid](0,-0.3)(3,3.3)
  \pnode(1,2.5){A}\pnode(2.5,1){B}
  \psset{optboxsize=1 0.6}
  \optbox[position=start](A)(B|A)
  \optbox[position=end](B|A)(B)
  \drawfiber[fiberstyle=angle, linearc=0.5]{1}{2}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \newpage
% \ifGERMAN\section{Schritt-für-Schritt-Beispiele}\fi
% \ifENGLISH\section{Step-by-step examples}\fi
% \label{sec:step-by-step}
%
% \ifGERMAN
% \subsection{Freistrahlaufbau}
% In diesem ersten Beispiel werden alle Komponenten auf eine Verbindungslinie
% verteilt und mit einem Strahl verbunden.
%
% Zuerst werden Anfangsknoten \prm{A} und Endknoten \prm{B} definiert. Die erste
% \Lcs{optbox} wird an den Anfang platziert, die Wellenplatte und der
% Polarisator werden innerhalb der Verbindungslinie positioniert. Der Parameter
% \Lkeyword{position} erwartet Werte zwischen \opt{0} und \opt{1}, die relativ
% zur Länge der Verbindungslinie sind, oder \opt{start}/\opt{end}. Der Detektor
% wird immer an das Ende der Linie gesetzt.
%
% Zuletzt werden alle Komponenten mit einem einfachen Lichtstrahl verbunden.
% \fi
% \ifENGLISH
% In this first example, all components are distributed on a single line and
% connected with a beam.
%
% First we define the start node \prm{A} and the stop node \prm{B}. The first
% \Lcs{optbox} is positioned at the start, the wave plate and the polarizer are
% positioned between the nodes. The parameter \Lkeyword{position} expects a
% value between \opt{0} and \opt{1} which is relative to the length of the
% reference line, or \opt{start}/\opt{end}. The detector is always positioned at
% the end of its reference line.
%
% Finally, all components are connected with a simple beam ray.
% \fi
% \iffalse
%<*ignore>
% \fi
\begingroup
\catcode`\*=13
\def*{}%
\begin{LTXexample}[style=example, linerange={1-7,10-10}]
\begin{pspicture}[showgrid](4,2)
  \pnode(1,1){A}\pnode(3,1){B}
  \optbox[position=start, optboxwidth=1.2, labeloffset=0](A)(B){Laser}
  \optretplate[position=0.3](A)(B){$\nicefrac{\lambda}{2}$}
  \optplate[position=0.7](A)(B){pol}
  \optdetector[dettype=diode](A)(B){PD}
  \drawbeam{1}{2}{3}{4}
  \psset{style=Refline, dotscale=1.5}\psdot(A)\psdot(B)
  \uput[45](A){\color{Refline}A}\uput[135](B){\color{Refline}B}
\end{pspicture}
\end{LTXexample}
\endgroup
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN\subsection{Galilei-Fernrohr}\fi
% \ifENGLISH\subsection{Galilean telescope}\fi
% \label{ex:galileo}
%
% \ifGERMAN 
% Im Folgenden wird ein sehr einfacher Aufbau mit einer konkaven und
% einer konvexen Linse schrittweise erläutert.
%
% Zuerst werden die Referenzknoten \prm{A} und \prm{B} definiert, die für die
% Ausrichtung der Komponenten verwendet werden. Zur besseren Übersicht werden
% beide Knoten gekennzeichnet, desweiteren dient ein Koordinatengitter der
% Orientierung.
%
% Die erste Linse soll konkav gekrümmte Grenzflächen haben. Mit
% \Lkeyword{lensradius} werden die Radien der linken und rechten Fläche auf
% negative Werte gesetzt, was eine konkave Krümmung ergibt. Die Linse wird mit
% \Lkeyword{abspos} eine Einheit vom \prm{A}-Knoten entfernt positioniert.
% \fi
% \ifENGLISH
% This example describes a simple setup with a concave and a convex lens and the
% raytracing through them.
%
% First, we define the reference nodes \prm{A} and \prm{B} which are used for
% alignment of the components. For better overview, these nodes are highlighted
% and a grid is drawn.
%
% The first lens should have concave interfaces. With \Lkeyword{lensradius} the
% interface radii are set to negative values, which correspond to concave
% curvatures. With \Lkeyword{abspos} the lens is positioned one unit from
% \prm{A} node.
% \fi
% \iffalse
%<*ignore>
% \fi
\begingroup
\catcode`\*=13
\def*{}%
\begin{LTXexample}[style=example, linerange={1-4,6-6}]
*\ON*\begin{pspicture}[showgrid](0,-0.3)(5,2.3)
  \pnode(0,1){A}\pnode(3.5,1){B}*\OFF*
  \lens[lensradius=-0.7,
          abspos=1](A)(B){concave}*\ON*
  \psset{style=Refline}\psdot(A)\psdot(B)
\end{pspicture}*\OFF*
\end{LTXexample}
\endgroup
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN
% Die zweite Linse bekommt eine konvexe Krümmung (\Lkeyword{lensradius}
% ist positiv) und wird \opt{2.6} Einheiten von \prm{A}
% positioniert. Die Linsenhöhe wird mit \Lkeyword{lensheight}
% eingestellt.
% \fi
% \ifENGLISH
% The second lens has a convex curvature (\Lkeyword{lensradius} is positive) and
% is positioned \opt{2.6} units apart from \prm{A}. Parameter
% \Lkeyword{lensheight} sets the total height of the lens.
% \fi
% \iffalse
%<*ignore>
% \fi
\begingroup
\catcode`\*=13
\def*{}%
\begin{LTXexample}[style=example, linerange={1-6,9-9}]
*\ON*\begin{pspicture}[showgrid](0,-0.3)(5,2.3)
  \pnode(0,1){A}\pnode(3.5,1){B}
  \lens[lensradius=-0.7, 
          abspos=1](A)(B){concave}*\OFF*
  \lens[lensradius=2.3, lensheight=1.3, 
          abspos=2.6](A)(B){convex}*\ON*
  \psset{style=Refline}\psdot(A)\psdot(B)
  \uput[45](A){\color{Refline}A}\uput[135](B){\color{Refline}B}
\end{pspicture}*\OFF*
\end{LTXexample}
\endgroup
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN
% Die Lichtstrahlen sollen auf einer CCD-Kamera enden, die mit einer
% \Lcs{optbox} gezeichnet wird. Mit \Lkeyword{position}\opt{=end} wird die Box
% ans Ende der Referenzlinie von \prm{A} nach \prm{B} gesetzt, die
% Beschriftung wird mit \Lkeyword{labeloffset} in die Mitte der Komponente
% gelegt.
% \fi
% \ifENGLISH
% The beam rays are supposed to end at the CCD camera which is drawn as a
% \Lcs{optbox}. With \Lkeyword{position}\opt{=end} the box is positioned at
% the end of the reference line from \prm{A} to \prm{B}. The label is put at
% the center of the component with \Lkeyword{labeloffset}.
% \fi
% \iffalse
%<*ignore>
% \fi
\begingroup
\catcode`\*=13
\def*{}%
\begin{LTXexample}[style=example, linerange={1-7,10-10}]
*\ON*\begin{pspicture}[showgrid](0,-0.3)(5,2.3)
  \pnode(0,1){A}\pnode(3.5,1){B}
  \lens[lensradius=-0.7,
          abspos=1](A)(B){concave}
  \lens[lensradius=2.3, lensheight=1.3, 
          abspos=2.6](A)(B){convex}*\OFF*
  \optbox[position=end, labeloffset=0](A)(B){CCD}*\ON*
  \psset{style=Refline}\psdot(A)\psdot(B)
  \uput[45](A){\color{Refline}A}\uput[135](B){\color{Refline}B}
\end{pspicture}*\OFF*
\end{LTXexample}
\endgroup
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN
% Zum Schluß wird ein aufgeweiteter Strahl mit einer Strahlbreite von \opt{0.2}
% und ohne anfängliche Divergenz durch die Komponenten geschickt. Der
% Strahlengang wird mittels Raytracing berechnet. Die Linsenparameter in diesem
% Beispiel wurden so gewählt das bei kollimiertem Eingangsstrahl der
% Ausgangsstrahl ebenfalls kollimiert ist.
% \fi
% \ifENGLISH
% Finally, a wide beam with an initial beam width of \opt{0.2} without
% divergence is sent through the components. The beam path is calculated by
% raytracing. The lens parameters in this example were set such, that for a
% collimated input beam also the output beam is collimated.
% \fi
% \iffalse
%<*ignore>
% \fi
\begingroup
\catcode`\*=13
\def*{}%
\begin{LTXexample}[style=example]
*\ON*\begin{pspicture}(5,2)
  \pnode(0,1){A}\pnode(3.5,1){B}
  \lens[lensradius=-0.7, 
          abspos=1](A)(B){concave}
  \lens[lensradius=2.3, lensheight=1.3, 
          abspos=2.6](A)(B){convex}
  \optbox[position=end, labeloffset=0](A)(B){CCD}*\OFF*
  \drawwidebeam[beamwidth=0.2](A){1}{2}{3}*\ON*
\end{pspicture}*\OFF*
\end{LTXexample}
\endgroup
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN
% Das Aussehen des Lichtstrahls wird über den \Lstyle{Beam}-Stil
% eingestellt, und kann z.B. mit einer halbtransparenten Füllung
% versehen werden.
% \fi
% \ifENGLISH
% The appearance of the beam can be changed via the \Lstyle{Beam} style, and may
% have e.g. a semitransparent fill pattern.
% \fi
% \iffalse
%<*ignore>
% \fi
\begingroup
\catcode`\*=13
\def*{}%
\begin{LTXexample}[style=example]
*\ON*\begin{pspicture}(5,2)
  \pnode(0,1){A}\pnode(3.5,1){B}
  \lens[lensradius=-0.7, 
          abspos=1](A)(B){concave}
  \lens[lensradius=2.3, lensheight=1.3, 
          abspos=2.6](A)(B){convex}
  \optbox[position=end, labeloffset=0](A)(B){CCD}*\OFF*
  \addtopsstyle{Beam}{fillstyle=solid, 
    fillcolor=green, opacity=0.2}
  *\ON*\drawwidebeam[beamwidth=0.2](A){1}{2}{3}
\end{pspicture}*\OFF*
\end{LTXexample}
\endgroup
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN\subsection{Faseraufbau}\fi
% \ifENGLISH\subsection{Fiber setup}\fi
% \label{sec:fiber-setup}
%
% \ifGERMAN
% Dieses Beispiel zeigt, wie ein faseroptischer Aufbau mit automatisch
% gezeichneten Faserverbindungen konstruiert werden kann.
%
% Auch hier werden die Referenzknoten zur besseren Orientierung
% eingezeichnet. Im Gegensatz zum vorhergehenden Beispiel benötigen wir
% mehr Referenzknoten, da die Faserkomponenten direkt mit diesen
% verbunden werden.
%
% Der Laser wird wieder an den Anfang gesetzt. Der Abstand
% der Beschriftung wird mit dem Parameter \Lkeyword{label} eingestellt,
% mit dem alle Beschriftungsparameter gesammelt eingestellt werden
% können. Da eine \Lcs{optbox} sowohl als Freistrahl- als auch als
% Faserkomponente verwendet werden kann, wird in der Standardeinstellung
% keine Faser gezeichnet, was mit \Lkeyword{fiber} geändert werden
% kann. Die Breite dieser und aller folgenden \Lcs{optbox} wird auf
% \opt{0.7} geändert.
% \fi
% \ifENGLISH
% This example shows how to setup a fiber drawing with automatic fiber
% connections.
%
% Again, the reference nodes are shown for better orientation. In contrast to
% the previous example, here, we need more reference nodes because the
% components are connected directly with them.
%
% The laser is set at the start. The label offset is set with the
% \Lkeyword{label} parameter, which would allow setting all label parameters at
% once. A \Lcs{optbox} is originally a free-ray component, so that for it the
% fiber connection must be enabled with \Lkeyword{fiber}. The width of all
% \Lcs{optbox} is changed to \opt{0.7}.
% \fi
% \iffalse
%<*ignore>
% \fi
% \begingroup
% \catcode`\*=13
% \def*{}%
\begin{LTXexample}[style=example, linerange={1-5,7-7}]
*\ON*\begin{pspicture}[showgrid](4.7,2)
  \pnode(0.7,1){A}\pnode(1,1){B}\pnode(2.8,1){C}
  \pnode(4,1.5){D}\pnode(4,0.5){E}*\OFF*
  \psset{optboxwidth=0.7, labelstyle=\scriptsize}
  \optbox[position=start, label=0, fiber](A)(B){LD}*\ON*
  \psset{style=Refline}\psdot(A)\psdot(B)\psdot(C)\psdot(D)\psdot(E)
\end{pspicture}*\OFF*
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN
% Als nächstes wird ein Mach-Zehnder-Modulator ohne Beschriftung gezeichnet, der
% automatisch mit Fasern mit seinen Referenzknoten verbunden wird.
% \fi
% \ifENGLISH The Mach--Zehner modulator is drawn without label and connected
% automatically with fibers to its reference nodes.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[style=example, linerange={1-6,8-8}]
*\ON*\begin{pspicture}[showgrid](4.7,2)
  \pnode(0.7,1){A}\pnode(1,1){B}\pnode(2.8,1){C}
  \pnode(4,1.5){D}\pnode(4,0.5){E}
  \psset{optboxwidth=0.7, labelstyle=\scriptsize}
  \optbox[position=start, label=0, fiber](A)(B){LD}*\OFF*
  \optmzm(B)(C)*\ON*
  \psset{style=Refline}\psdot(A)\psdot(B)\psdot(C)\psdot(D)\psdot(E)
\end{pspicture}*\OFF*
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN
% Danach wird ein Faserkoppler mit einem Eingang und zwei Ausgängen
% gezeichnet. Der Koppler wird zwischen dem Eingangsknoten und dem
% Mittelpunkt der beiden Ausgangsknoten ausgerichtet. 
% \fi
% \ifENGLISH Then, we draw a fiber coupler with one input and two output
% fibers. The coupler is positioned between the input node and the center of the
% two output nodes.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[style=example, linerange={1-7,9-9}]
*\ON*\begin{pspicture}[showgrid](4.7,2)
  \pnode(0.7,1){A}\pnode(1,1){B}\pnode(2.8,1){C}
  \pnode(4,1.5){D}\pnode(4,0.5){E}
  \psset{optboxwidth=0.7, labelstyle=\scriptsize}
  \optbox[position=start, label=0, fiber](A)(B){LD}
  \optmzm(B)(C)*\OFF*
  \wdmsplitter(C)(D)(E){50\%}*\ON*
  \psset{style=Refline}\psdot(A)\psdot(B)\psdot(C)\psdot(D)\psdot(E)
\end{pspicture}*\OFF*
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \ifGERMAN 
% An die Enden des Kopplers wird ein optischer Spektrumanalysator (OSA) und eine
% Leistungsmessgerät (PD) gesetzt. Der \Lcs{optdetector} wird immer ans Ende der
% Referenzlinie gesetzt (\Lkeyword{position}\opt{=end}). Diese beiden
% Komponenten werden ohne weitere Einstellungen ohne Faserverbindungen
% gezeichnet. Das passt, da ihre jeweiligen Endpunkte mit den Ausgängen des
% Kopplers zusammenfallen.
%
% Die Schreibweise \opt{(A|E)} nimmt die $x$-Koordinate von \prm{A} und die
% $y$-Koordinate von \prm{E}.
% \fi
% \ifENGLISH
% At the ends of the coupler we put an optical spectrum analyzer (OSA) and a
% power meter (PD). The \Lcs{optdetector} is always set at the end of the
% reference line, it has \Lkeyword{position} fixed to \opt{end}. These two
% components are drawn without fibers, because their end nodes coincide with the
% two outputs of the coupler.
%
% The notation \opt{(A|E)} uses the $x$-coordinate of \prm{A} and the
% $y$-coordinate of \prm{E}.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[style=example, caption={caption}, label={ex:fiber-setup}, linerange={1-9,11-11}]
*\ON*\begin{pspicture}[showgrid](4.7,2)
  \pnode(0.7,1){A}\pnode(1,1){B}\pnode(2.8,1){C}
  \pnode(4,1.5){D}\pnode(4,0.5){E}
  \psset{optboxwidth=0.7, labelstyle=\scriptsize}
  \optbox[position=start, label=0, fiber](A)(B){LD}
  \optmzm(B)(C)
  \wdmsplitter[abspos=0.3, label=0.4](C)(D)(E){50\%}*\OFF*
  \optbox[position=end, label=0](A|D)(D){OSA}
  \optdetector(A|E)(E){PD}*\ON*
  \psset{style=Refline}\psdot(A)\psdot(B)\psdot(C)\psdot(D)\psdot(E)
\end{pspicture}*\OFF*
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN\subsection{Faseraufbau (Alternative)}\fi
% \ifENGLISH\subsection{Fiber setup (alternative)}\fi
%
% \ifGERMAN
% Dieses Beispiel ist vom Ergebnis her identisch mit dem vorangegangenen
% (\prettyref{ex:fiber-setup}), wird aber anders angegangen.
%
% Hier verwenden wir nicht die automatischen Faserverbindungen sondern zeichnen,
% wie bei Freistrahlaufbauten, zuerst die Komponenten und verbinden diese zum
% Schluß explizit mit Fasern (\Lcs{drawfiber}). Daher benötigen wir weniger
% Referenzknoten, die Faserverbindungen werden mit \Lkeyword{fiber}\opt{=none}
% global unterdrückt.
%
% Welche Herangehensweise verwendet wird ist meistens Geschmackssache, bei
% Ringstrukturen wie z.B. Faserlasern kann das nachträgliche Verbinden mit
% \Lcs{drawfiber} von Vorteil sein.
% \fi
%
% \ifENGLISH 
% This example has the same result as the previous one
% (\prettyref{ex:fiber-setup}), but is constructed differently.
%
% This time we do not use the automatic fiber connections, but draw all
% components first and connect them afterwards with fibers
% (\Lcs{drawfiber}). This requires less reference nodes, the fiber connections
% are suppressed globally with \Lkeyword{fiber}\opt{=none}.
%
% The choice of the procedure depends on personal preferences, for loop setups,
% like for fiber lasers, it looks better if the fibers are drawn after the
% components with \Lcs{drawfiber}.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[style=example, caption={caption}, linerange={1-10,13-13}]
\begin{pspicture}[showgrid](4.9,2)
  \pnode(0.7,1){A}\pnode(4,1){B}
  \psset{optboxwidth=0.7, labelstyle=\scriptsize, fiber=none}
  \optbox[position=start, labeloffset=0](A)(B){LD}
  \optmzm[abspos=1.1](A)(B)
  \wdmsplitter[abspos=2.25, label=0.4](A)(B)(B){50\%}
  \optbox[position=end,label=0, compshift=0.5](A)(B){OSA}
  \optdetector[compshift=-0.5](A)(B){PD}
  \drawfiber{1}{2}{3}{4}
  \drawfiber{3}{5}
  \psset{style=Refline}\psdot(A)\psdot(B)
  \color{Refline}\uput[45](A){A}\uput[135](B){B}
\end{pspicture}
\end{LTXexample}
% \endgroup
% \iffalse
%</ignore>
% \fi 
% 
% \ifGERMAN
% \newpage
% \subsection{Michelson-Interferometer}
% \fi
% \ifENGLISH
% \subsection{Michelson-Interferometer}
% \fi
% \label{ex:michelson}
%
% \ifGERMAN
% In diesem Beispiel werden neben Linsen auch reflektierende Elemente
% (Spiegel) eingesetzt sowie Elemente, die sowohl transmittieren als
% auch reflektieren (Strahlteiler).
% \fi
% \ifENGLISH
% In this example we use lenses, reflective elements (mirrors) and components
% which can be either transmittive or reflective (beamsplitter).
% \fi
%
% \begingroup
% \catcode`\*=13
% \def*{}%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[style=example, hsep=8mm, numbers=left, numberstyle=\footnotesize, caption={caption}]
\begin{pspicture}(3.2,5)
  \pnode(0,3){A}\pnode(1,3){BS}\pnode(3,3){M1}*\label{l:ex2-nodes1}*
  \pnode(1,5){M2}\pnode(1,1){PD}*\label{l:ex2-nodes2}*
  \psset{mirrortype=extended, mirrordepth=0.2}*\label{l:ex2-set}*
  \begin{optexp}*\label{l:ex2-begin}*
    \beamsplitter[bsstyle=plate, compname=BS](A)(BS)(PD)*\label{l:ex2-bs}*
    \mirror[compname=M1](BS)(M1)(BS)*\label{l:ex2-m1}*
    \mirror[compname=M2, variable](BS)(M2)(BS)*\label{l:ex2-m2}*
    \lens[compname=L](BS)(PD)*\label{l:ex2-l}*
    \optdetector[compname=Det, dettype=diode](BS)(PD)*\label{l:ex2-det}*
    \addtopsstyle{Beam}{beamwidth=0.2, fillstyle=solid, fillcolor=green!20!white}*\label{l:ex2-style}*
    \drawwidebeam(A){BS}{M1}{BS}{M2}{BS}{L}{Det}*\label{l:ex2-beam}*
  \end{optexp}
\end{pspicture}
\end{LTXexample}
% \endgroup
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN
% Wir beginnen wieder, indem wir die Referenzknoten definieren
% (\prettyref{l:ex2-nodes1}--\ref{l:ex2-nodes2}) und ein paar
% grundlegende Einstellungen setzen (\prettyref{l:ex2-set}).
%
% Dann werden der Reihe nach alle Komponenten platziert
% (\prettyref{l:ex2-bs}--\ref{l:ex2-det}). Die reflektierenden benötigen
% drei Referenzknoten: den Eingangsknoten, den Knoten an dem die
% reflektierende Grenzfläche ist und den Ausgangsknoten. Anschließend
% wird noch das Aussehen des Lichtstrahls festgelegt
% (\prettyref{l:ex2-style}) und der Strahl gezeichnet
% (\prettyref{l:ex2-beam}).
%
% Diese Mal haben wir den Komponenten Namen gegeben (\Lkeyword{compname}) die
% beim Raytracing anstelle der IDs -- der automatisch vergebenen Nummern --
% verwendet werden können. Dies kann die Nachverfolgung des Strahlengangs
% erleichtern.
% 
% Alle Komponenten und Strahlen wurden zusätzlich in eine
% \Lenv{optexp}-Umgebung gekapselt. Innerhalb dieser werden alle
% Lichtstrahlen hinter die Komponenten gelegt, sodass diese nicht
% verdeckt werden.
% \fi
% \ifENGLISH
% We start with definition of the reference nodes
% (\prettyref{l:ex2-nodes1}--\ref{l:ex2-nodes2}) and setting some basic
% parameters (\prettyref{l:ex2-set}).
%
% Following, all components are positioned
% (\prettyref{l:ex2-bs}--\ref{l:ex2-det}). The reflective ones need three
% reference nodes, the input node, the node where the reflective interface is
% situated, and the output node. Then, the appearance of the beam is set
% (\prettyref{l:ex2-style}), and the beam is drawn (\prettyref{l:ex2-beam}).
%
% In this example, all components have a name (\Lkeyword{compname}), which can
% be used instead of the numerical IDs---automatically assigned, unique
% numbers---for the raytracing. This can simplify follwing the beam path.
%
% All components and beams are enclosed in a \Lenv{optexp} environment. Inside
% of this, all beams are drawn behind the components.
% \fi
%
%
% \ifGERMAN\chapter{Allgemeine Komponentenparameter}\fi
% \ifENGLISH\chapter{General component parameters}\fi
% \label{chap:generalparam}
% 
% \ifGERMAN Dieses Kapitel enthält alle Informationen zu allgemeinen Parametern
% und Konzepten. Das beinhaltet das Setzen von Beschriftungen
% (\ref{sec:labels}), Positionierung (\ref{sec:positioning}), Drehen und
% Verschieben von Komponenten (\ref{sec:rotshift}) und Anpassen der Aussehens
% (\ref{sec:styles} und \ref{sec:appearance}).
% \fi
% \ifENGLISH This chapter introduces generic parameters and concepts such as
% labels (\ref{sec:labels}), positioning (\ref{sec:positioning}), rotating and
% shifting of components (\ref{sec:rotshift}) and changing the appearance of
% components (\ref{sec:styles} and \ref{sec:appearance}).
% \fi
%
% \ifGERMAN\section{Beschriftungen}\fi
% \ifENGLISH\section{Labels}\fi
% \label{sec:labels}
%
% \ifGERMAN Alle Komponenten können mit einer Beschriftung versehen werden,
% deren Position und Ausrichtung genau angepasst werden kann. Die Beschriftung
% ist für jede Komponente optional. Sollten die vielfältigen Parameter nicht
% ausreichend sein, können Sie den Beschriftungsknoten -- in einigen Beispielen
% mit einem roten Punkt gekennzeichnet -- auch direkt verwenden (siehe auch
% \prettyref{sec:labelnode}). 
% \fi
% \ifENGLISH All components may have a label which position and alignment can be
% adjusted at will. The label is optional for every component. If the various
% parameters are not sufficient, you can access the label node---marked as red
% dot in some examples---directly (see also \prettyref{sec:labelnode}).
% \fi 
%
% \begin{optionlist}
% \numitem[0.8]{labeloffset}
% \ifGERMAN Der Abstand des Referenzknotens für die Beschriftung (roter Punkt) zur Komponentenmitte (blaues Kreuz).\fi
% \ifENGLISH The offset of the label reference node (red dot) from the component
% center (blue cross).\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-2,6-6}, morekeywords={[21]{labeloffset}}]
\begin{pspicture}(3,1.8)
  \optbox[beam, labeloffset=1](0,1.5)(3,0.8){label}
  \psdot[style=CenterNode](\oenodeCenter{})
  \psdot[linecolor=red](\oenodeLabel{})
  \ncline[arrows=<->, style=Refline, arrowinset=0, arrowscale=1.5]{\oenodeCenter{}}{\oenodeLabel{}}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \valitem{labelstyle}{macros}
% \ifGERMAN Der Schriftstil der Beschriftungen.\fi
% \ifENGLISH The text style that is used to typeset the label.\fi
% 
% \valitem[c]{labelalign}{refpoint}
% \ifGERMAN Definiert die Ausrichtung der Beschriftung bezüglich des
% Beschriftungsknotens.
% \fi
% \ifENGLISH Defines the alignment of the label relative to the label node.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-3,6-6}, morekeywords={[21]{labeloffset, labelalign}}]
\begin{pspicture}(3,1.8)
  \psset{beam, labeloffset=1}
  \optbox[labelalign=bl](0,1.5)(3,0.8){label}
  \psdot[style=CenterNode](\oenodeCenter{})
  \psdot[linecolor=red](\oenodeLabel{})
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \numitem[0]{labelangle}
% \ifGERMAN
% Der Rotationswinkel des Beschriftungsknotens um die Mitte. Der Nullpunkt hängt
% sowohl von der jeweiligen Komponenten und dem gewählten Referenzsystem ab
% (siehe \Lkeyword{labelref}).
% \fi
% \ifENGLISH
% The rotation angle of the label node around the component center. The origin
% depends both on the component and the choosen reference system (see
% \Lkeyword{labelref}).
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-2,4-6,27-27}, morekeywords={[21]{labelangle}}]
\begin{pspicture}(-0.3,0)(2,3.7)
  \psset{labeloffset=1, optboxwidth=1, arrowscale=1.5, arrowinset=0}
  \begin{optexp}
  \optbox[position=end, labelangle=90](1,1)(1,2){Box}
  \beamsplitter[labelangle=-90](1,2)(1,1)(2,1){BS}
  \drawbeam[arrows=->]{1}{2}(2,1)
  \frontlayer{%
    \psdot[style=CenterNode](\oenodeCenter{1})
    \psdot[style=CenterNode](\oenodeCenter{2})
    \psdot[linecolor=red](\oenodeLabel{1})
    \psdot[linecolor=red](\oenodeLabel{2})
  }
  \backlayer{%
    \bgroup
    \psset{style=Refline}
    \psline(\oenodeCenter{2})([offset=-1]\oenodeCenter{2})
    \psline(\oenodeCenter{2})([Xnodesep=-1]\oenodeCenter{2})
    \psarc[arrows=<-](\oenodeCenter{2}){0.7}{180}{270}
    \uput{0.9}[-135](\oenodeCenter{2}){\small $-90$\textdegree}
    \psline(\oenodeCenter{1})([Xnodesep=1]\oenodeCenter{1})
    \psline(\oenodeCenter{1})([offset=1]\oenodeCenter{1})
    \psarc[arrows=->](\oenodeCenter{1}){0.7}{0}{90}
    \uput{0.9}[45](\oenodeCenter{1}){\small $90$\textdegree}
    \egroup
  }
  \end{optexp}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \choitem[relgrav]{labelref}{relative, relgrav, global, absolute}
% \ifGERMAN
% Wählt das Bezugssystem für \Lkeyword{labelangle} und die Orientierung der
% Beschriftung.
% \fi
% \ifENGLISH
% Set the reference coordinate system for the \Lkeyword{labelangle} and the
% orientation of the label text.
% \fi
%
%   \begin{valuelist}
%   \item[relative] 
%     \ifGERMAN Die Beschriftung ist parallel zu der Referenzlinie der
%     Komponente und der Winkel wird immer auf den Bereich zwischen $-90$° und
%     $+90$° zurückgerechnet.
%     \fi
%     \ifENGLISH The label is parallel to the component reference line and the
%     actual angle is always projected to the range between $-90$° and $+90$°.
%     \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{labelref}}]
\begin{pspicture}(0,-2.2)(2,2.2)
  \psset{position=end, optboxsize=1 0.6, labeloffset=0, labelref=relative}
  \multido{\i=0+45}{8}{%
    \optbox(0,0)(1;\i){\i}
  }
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
%   \item[relgrav]
%     \ifGERMAN Die Beschriftung ist immer horizontal, lediglich der
%     Beschriftungsknoten wird zusammen mit der Komponente gedreht.
%     \fi
%     \ifENGLISH The label itself is always horizontal, only the label node is
%     rotated together with the component.
%     \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{labelref}}]
\begin{pspicture}(0,-2.2)(2,2.2)
  \psset{position=end, optboxsize=1 0.6, labelref=relgrav}
  \multido{\i=0+72}{5}{%
    \optbox(0,0)(1;\i){\i}
  }
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
%   \item[global, absolute]
%   \ifGERMAN Die Beschriftung ist unabhängig von der Komponentenausrichtung.\fi
%   \ifENGLISH The label is independent of the component alignment.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{labelref}}]
\begin{pspicture}(0,-2.2)(2,2.2)
  \psset{position=end, optboxsize=1 0.6, labelref=global}
  \multido{\i=0+72}{5}{%
    \optbox(0,0)(1;\i){\i}
  }
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{valuelist}
% 
% \optitem{label}{\prm{offset}[ \prm{angle}[ \prm{refpoint}[ \prm{labelref}]]]}
% \ifGERMAN
% Diese Option erlaubt die kompakte Definition mehrerer
% Beschriftungsparameter. Es können bis zu vier Leerzeichen-getrennte
% Argumente übergeben werden (\Lkeyword{labeloffset},
% \Lkeyword{labelangle}, \Lkeyword{labelalign} und
% \Lkeyword{labelref}). Mit einem Punkt kann eine Option übersprungen
% werden.
% \fi
% \ifENGLISH
% Allows compact definition of several label parameters. It takes up to
% four space-separated arguments (\Lkeyword{labeloffset},
% \Lkeyword{labelangle}, \Lkeyword{labelalign}, and
% \Lkeyword{labelref}). Unchanged intermediate arguments can be
% skipped with a dot.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{label}}]
\begin{pspicture}(0,0)(4,3)
  \psset{endbox, beam}
  \optbox[label=0.7](1.5,2.5)(2.5,2.5){box}
  \optbox[label=1 -45](1.5,1)(2.5,1){$-45$}
  \optbox[label=0 . . relative]%
         (0.6,0.6)(0.6,1.6){relative}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \choitem{innerlabel}{true}
% \ifGERMAN Das ist ein Alias für \opt{label=0 .\ .\ relative}\fi
% \ifENGLISH This is an alias for \opt{label=0 .\ .\ relative}\fi
% \end{optionlist}
%
%
%
% \ifGERMAN\section{Positionierung}\fi
% \ifENGLISH\section{Positioning}\fi
% \label{sec:positioning}
%
% \ifGERMAN
% Alle Komponenten außer den Freistrahl-Dreipolen können zwischen ihren
% beiden Referenzknoten \Lcs{oenodeRefA} und \Lcs{oenodeRefB}
% positioniert werden.
% \fi
% \ifENGLISH
% All components except for the free-ray tripoles can be positioned between
% their two reference nodes \Lcs{oenodeRefA} and \Lcs{oenodeRefB}.
% \fi
% \begin{optionlist}
%   \choitem{position}{\prm{num},start,end}
%   \ifGERMAN 
%   Ist der Wert eine Zahl, so wird damit die relative Position der Mitte eines
%   Objektes (blaues Kreuz) bezüglich seiner beiden Referenzknoten (schwarze
%   Punkte) gesetzt. Das ist äquivalent zum \Lkeyword*{npos} Parameter von
%   \Lcs*{ncput}, d.h. eine Zahl im Intervall $[0,1]$ (siehe \LPack{pst-node}
%   Dokumentation\fnurl{http://mirror.ctan.org/help/Catalogue/entries/pst-node.html}).
%   \fi
%   \ifENGLISH Controls the relative position of an object center (blue cross)
%   between its two reference points (black dots), if the value is a number. In
%   this case it is equivalent to the \Lkeyword*{npos} parameter of
%   \Lcs*{ncput}, i.e. a number in the range $[0,1]$ (see \LPack{pst-node}
%   documentation\fnurl{http://mirror.ctan.org/help/Catalogue/entries/pst-node.html}).
%   \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{position}}, linerange={1-2,5-5}]
\begin{pspicture}(3,1.5)
  \lens[beam, position=0.8](0,1)(3,1){L}
  \psdot(\oenodeRefA{})\psdot(\oenodeRefB{})
  \psdot[style=CenterNode](\oenodeCenter{})
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN 
% Der Wert \opt{start} setzt ein Objekt an den Anfang, \opt{end} ans Ende der
% Referenzlinie, so dass die entsprechende Grenzfläche auf dem Referenzknoten
% (schwarzer Punkt) liegt, und nicht die Mitte des Objektes (blaues Kreuz), wie
% es mit \opt{position=1} bzw. \opt{position=0} der Fall wäre. Unter Verwendung
% von Zahlen wäre dieses Verhalten deutlich schwieriger und weniger flexibel zu
% erreichen, da die Größe und Form des Objektes berücksichtigt werden muss.
% \fi
% \ifENGLISH
% The values \opt{start} and \opt{end} place an object at the start or end of
% the reference line, respectively. The respective object interface is placed on
% the respective reference node (black dot) instead of the object center (blue
% cross) which would be the case for \opt{position=0} or
% \opt{position=1}. Achieving this with numerical values would me more difficult
% and unflexible, because the object size and shape must be taken into account.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{position}}, linerange={1-4,8-8}]
\begin{pspicture}(3,2)
  \pnode(0.5,1){A}\pnode(2.5,1){B}\psdot(A)\psdot(B)
  \optbox[optboxsize=0.5 0.5, position=start](A)(B)
  \lens[position=end](A)(B)
  \psline[style=Refline](A)(B)
  \psdot[style=CenterNode](\oenodeCenter{1})
  \psdot[style=CenterNode](\oenodeCenter{2})
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN Hier ist im Vergleich dazu die Positionierung mit
% \opt{position=0}/\opt{1}.
% \fi
% \ifENGLISH Here is for comparison the positioning with
% \opt{position=0}/\opt{1}.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{position}}, linerange={1-4,8-8}]
\begin{pspicture}(3,2)
  \pnode(0.5,1){A}\pnode(2.5,1){B}\psdot(A)\psdot(B)
  \optbox[optboxsize=0.5 0.5, position=0](A)(B)
  \lens[position=1](A)(B)
  \psline[style=Refline](A)(B)
  \psdot[style=CenterNode](\oenodeCenter{1})
  \psdot[style=CenterNode](\oenodeCenter{2})
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \choitem{abspos}{\prm{num},start,end}
% \ifGERMAN
% Eine Zahl setzt die absolute Position eines Objektes auf der
% Referenzlinie. Die Werte \opt{start} und \opt{end} werden identisch wie bei
% \Lkeyword{position} behandelt.
% \fi
% \ifENGLISH
% Controls the absolute position of an object on the reference line. The values
% \opt{start} and \opt{end} are handled identically to \Lkeyword{position}.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{abspos}}, linerange={1-2,5-5}]
\begin{pspicture}(3,1.5) 
  \lens[beam, abspos=1](0,1)(3,1){L}
  \psdot(\oenodeRefA{})\psdot(\oenodeRefB{})
  \psdot[style=CenterNode](\oenodeCenter{})
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \boolitem{endbox}
% \ifGERMAN Dieser Parameter ist äquivalent zu \Lkeyword{position}\opt{=end}.\fi
% \ifENGLISH This parameter is equivalent to \Lkeyword{position}\opt{=end}.\fi
% \end{optionlist}
% 
%
%
% \ifGERMAN\section{Drehen und Verschieben}\fi
% \ifENGLISH\section{Rotating and shifting}\fi
% \label{sec:rotshift}
%
% \ifGERMAN
% Alle Komponenten können versetzt und um verschiedene Bezugspunkte
% gedreht werden. 
%
% Beachten Sie, dass mit den Komponenten auch die Grenzflächenknoten
% (\prettyref{sec:ifcnode}, in den folgenden Beispielen mit blauen Kreuzen
% markiert) transformiert werden, wodurch Verbindungen beinflußt werden. Die
% transformierten Referenzknoten sind als eigene Knoten verfügbar
% (\prettyref{sec:refnode}).
% \fi
% \ifENGLISH 
% All components can be shifted and rotated around different reference nodes.
%
% Please note, that together with the components also their interface nodes
% (\prettyref{sec:ifcnode}, marked as blue crosses in the following examples)
% are transformed, which may impact the connections. The transformed reference
% nodes are accessible as new nodes (\prettyref{sec:refnode}).
% \fi
% 
% \begin{optionlist}
% \numitem[0]{angle}
% \ifGERMAN Dreht eine Komponente um den Winkel \prm{num} (in Grad). Die
% Ausgangsposition ist grau gestrichelt eingezeichnet.
% \fi
% \ifENGLISH Rotate a component by an angle \prm{num} (in degree). The original
% position is drawn gray dashed.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-2,4-4,10-10}, morekeywords={[21]{angle}}]
\begin{pspicture}(3,2)
  \pnode(0,1){A}\pnode(2.7,1){B}
  \optbox[addtoOptComp={style=Refline, linestyle=dashed}](A)(B)
  \optbox[angle=20, innerlabel](A)(B){box}
  \psline[style=Refline](\oenodeRefA{})(\oenodeRefB{})
  \psdot(\oenodeRefA{})\uput[-90](\oenodeRefA{}){RefA}
  \psdot(\oenodeRefB{})\uput[-90](\oenodeRefB{}){RefB}
  \psdot[style=CenterNode](\oenodeIn{})
  \psdot[style=CenterNode](\oenodeOut{})
\end{pspicture}
\end{LTXexample}
%\iffalse
%</ignore>
%\fi
%
% \valitem[c]{rotateref}{refpoint}
% \ifGERMAN
% Setzt den Bezugspunkt für die Drehung der Komponente. Bitte lesen Sie
% \prettyref{sec:rotrefnode} für eine genauere Beschreibung und entnehmen Sie
% \prettyref{sec:overview-extnode} die möglichen Bezugspunkte für alle
% Komponenten. Die Ausgangsposition ist grau gestrichelt eingezeichnet.
% \fi
% \ifENGLISH
% Set the reference point for the rotation of the component. Please see
% \prettyref{sec:rotrefnode} for a detailed explanation and
% \prettyref{sec:overview-extnode} for a list of the possible reference nodes of
% all components. The original position is drawn gray dashed.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-2,4-4,10-10}, morekeywords={[21]{angle,rotateref}}]
\begin{pspicture}(3,2)
  \pnode(0,1){A}\pnode(2.7,1){B}
  \optbox[addtoOptComp={style=Refline, linestyle=dashed}](A)(B)
  \optbox[angle=20, rotateref=bl, innerlabel](A)(B){box}
  \psline[style=Refline](\oenodeRefA{})(\oenodeRefB{})
  \psdot(\oenodeRefA{})\uput[-90](\oenodeRefA{}){RefA}
  \psdot(\oenodeRefB{})\uput[-90](\oenodeRefB{}){RefB}
  \psdot[style=CenterNode](\oenodeIn{})
  \psdot[style=CenterNode](\oenodeOut{})
\end{pspicture}
\end{LTXexample}
%\iffalse
%</ignore>
%\fi
%
% \numitem[0]{compshift} 
% \ifGERMAN Verschiebt eine Komponente vertikal bezüglich ihrer Referenzlinie
% (siehe \prettyref{sec:refnode}). Reflektive Komponenten werden entlang der
% reflektiven Grenzfläche verschoben.
% \fi
% \ifENGLISH
% Shift a component perpendicular to its reference line (see
% \prettyref{sec:refnode}). For reflective components it is shifted along the
% reflective interface.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-3,9-9}, morekeywords={[21]{compshift}}]
\begin{pspicture}(3,2)
  \pnode(0,1){A}\pnode(2.7,1){B}
  \lens[compshift=0.3](A)(B){L}
  \psline[style=Refline](\oenodeRefA{})(\oenodeRefB{})
  \psdot(\oenodeRefA{})\uput[-90](\oenodeRefA{}){RefA}
  \psdot(\oenodeRefB{})\uput[-90](\oenodeRefB{}){RefB}
  \psdot[style=CenterNode](\oenodeIn{})
  \psdot[style=CenterNode](\oenodeOut{})
\end{pspicture}
\end{LTXexample}
\begin{LTXexample}[linerange={1-3,9-9}, morekeywords={[21]{compshift}}]
\begin{pspicture}(3,2) 
  \pnode(0,1){A}\pnode(2,0){B}
  \mirror[compshift=0.3](A)(2,1)(B){mirror}
  \psline[style=Refline](\oenodeRefA{})(\oenodeRefB{}|\oenodeRefA{})(\oenodeRefB{})
  \psdot(\oenodeRefA{})\uput[-90](\oenodeRefA{}){RefA}
  \psdot(\oenodeRefB{})\uput[180](\oenodeRefB{}){RefB}
  \psdot[style=CenterNode](\oenodeIn{})
  \psdot[style=CenterNode](\oenodeOut{})
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \numitem[0]{compoffset}
% \ifGERMAN Verschiebt eine Komponente vertikal bezüglich ihrer
% Referenzlinie (siehe \prettyref{sec:refnode}). Reflektierende
% Komponenten werden entlang der reflektiven Grenzfläche verschoben. Die
% Verschiebung erfolgt also senkrecht zu einer Verschiebung mit
% \Lkeyword{compshift}. Ein Anwendungsbeispiel ist
% \prettyref{ex:autocorrelation}.
% \fi
% \ifENGLISH
% Shift a component perpendicular to its reference line (see
% \prettyref{sec:refnode}). For reflective components it is shifted
% along the reflective interface. The displacement is vertical to a
% displacement with \Lkeyword{compshift}. For an example see
% \prettyref{ex:autocorrelation}.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-3,9-9}, morekeywords={[21]{compshift}}]
\begin{pspicture}(3,2)
  \pnode(0,1){A}\pnode(2.7,1){B}
  \lens[compoffset=0.3](A)(B){L}
  \psline[style=Refline](\oenodeRefA{})(\oenodeRefB{})
  \psdot(\oenodeRefA{})\uput[-90](\oenodeRefA{}){RefA}
  \psdot(\oenodeRefB{})\uput[-90](\oenodeRefB{}){RefB}
  \psdot[style=CenterNode](\oenodeIn{})
  \psdot[style=CenterNode](\oenodeOut{})
\end{pspicture}
\end{LTXexample}
\begin{LTXexample}[linerange={1-3,9-9}, morekeywords={[21]{compshift}}]
\begin{pspicture}(3,2) 
  \pnode(0,1){A}\pnode(2,0){B}
  \mirror[compoffset=0.3](A)(2,1)(B){mirror}
  \psline[style=Refline](\oenodeRefA{})(\oenodeRefB{}|\oenodeRefA{})(\oenodeRefB{})
  \psdot(\oenodeRefA{})\uput[-90](\oenodeRefA{}){RefA}
  \psdot(\oenodeRefB{})\uput[180](\oenodeRefB{}){RefB}
  \psdot[style=CenterNode](\oenodeIn{})
  \psdot[style=CenterNode](\oenodeOut{})
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \choitem{innercompalign}{rel, relative, abs, absolute}
% \ifGERMAN Ist dieser Parameter auf \opt{absolute} gesetzt, so wird das
% «Innere» einer Komponente nicht mitgedreht. Diese Option wird derzeit
% nur von \Lcs{optfilter} verwendet.
% \fi
% \ifENGLISH If this parameter is set to \opt{absolute}, the «inner»
% component part is not rotated with the component. At the moment, this
% option is used only by \Lcs{optfilter}. 
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
\psset[optexp]{labelangle=-90, position=start}
\optfilter[innercompalign=rel](0.5,1.2)(0.5,2){rel}
\optfilter[innercompalign=abs](2.5,1.2)(2.5,2){abs}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
%
%
% \ifGERMAN\section{Verwendung von Stilen}\fi
% \ifENGLISH\section{Using psstyles}\fi\label{sec:styles}
%
% \ifGERMAN
% Stile sind benutzerdefinierte Grafik-Konfigurationen für
% PSTricks-Objekte. Das \LPack{pst-optexp}-Paket macht umfangreichen
% Gebrauch von Stilen um einzelne, logische Bereiche von Komponenten
% flexibel gestalten zu können, was über das optionale Argument meistens
% nicht möglich ist. 
%
% Vorhandene Stile können mit \Lcs*{addtopsstyle} erweitert und mit
% \Lcs*{newpsstyle} überschrieben werden.
%
% Als Beispiel nehmen wir einen \opt{extended} Spiegel und möchten nur
% den «extended»-Teil verändern. Hierfür wird der Stil
% \Lstyle{ExtendedMirror} bereitgestellt:
% \fi
% \ifENGLISH
% Psstyles are custom graphics parameter configurations for PSTricks
% objects. The \LPack{pst-optexp} package makes extensive use of styles
% to facilitate flexible design of single, logical parts of
% components. This is in general not possible with the optional
% argument.
%
% Existing styles can be extended with \Lcs*{addtopsstyle} and
% overwritten with \Lcs*{newpsstyle}.
%
% As example we consider an \opt{extended} mirror and want to change
% only the «extended» part which is controlable with the
% \Lstyle{ExtendedMirror} style:
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
  \addtopsstyle{ExtendedMirror}{hatchcolor=red}
  \mirror[mirrortype=extended, beam](0,0)(2,1.5)(0,2)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \ifGERMAN 
% Die veränderbaren Unterbereiche einer Komponente sind in der
% jeweiligen Referenz zu finden.
% \fi
% \ifENGLISH 
% The changeable parts of each component are listed in the respective
% reference.
% \fi
%
%
%
% \ifGERMAN\section{Aussehen der Komponenten}\fi
% \ifENGLISH\section{Component appearance}\fi
% \label{sec:appearance}
%
% \begin{stylelist}
% \styleitem{OptComp} 
% \ifGERMAN
% Bestimmt das grundlegende Aussehen aller optischen Komponenten. Die
% üblichen Parameter, wie z.B. \opt{linestyle}, würden auch die
% Verbindungen beeinflussen, die mit der Komponente zusammen gezeichnet
% werden (\Lkeyword{beam}, \Lkeyword{fiber} usw.). Mit
% \Lkeyword{newOptComp} und \Lkeyword{addtoOptComp} kann der Stil für
% einzelne Komponenten oder zusammen mit \Lcs*{newpsobject} im optionalen
% Argument verwendet werden.
% \fi
% \ifENGLISH
% Affects the basic appearence of all optical components. Using standard
% graphics parameters like e.g.\ \opt{linestyle} would change also the
% connections that are drawn together with the component
% (\Lkeyword{beam}, \Lkeyword{fiber} etc.). Use the key
% \Lkeyword{newOptComp} and \Lkeyword{addtoOptComp} to change the style
% for single components or for use with \Lcs*{newpsobject} via the
% optional argument.
% \fi
% \iffalse
%<*ignore>
% \fi
\ifGERMAN
\begin{LTXexample}[morekeywords={[21]{addtoOptComp}}]
\begin{pspicture}(2.5,4)
  \psset{beam}
  % falsch, die Strahlbreite wird auch geaendert
  \mirror[linewidth=3\pslinewidth](0,3)(2,3)(2,2)
  % korrektes Ergebnis
  \addtopsstyle{OptComp}{linewidth=3\pslinewidth}
  \mirror(0,1)(2,1)(2,0)
\end{pspicture}
\end{LTXexample}
\fi\ifENGLISH
\begin{LTXexample}[morekeywords={[21]{addtoOptComp}}]
\begin{pspicture}(2.5,4)
  \psset{beam}
  % wrong, also beam width is changed
  \mirror[linewidth=3\pslinewidth](0,3)(2,3)(2,2)
  % correct result
  \addtopsstyle{OptComp}{linewidth=3\pslinewidth}
  \mirror(0,1)(2,1)(2,0)
\end{pspicture}
\end{LTXexample}
\fi
% \iffalse
%</ignore>
% \fi
%
% \styleitem[linestyle=dashed,dash=1.5pt 1pt]{OptionalStyle} 
% \ifGERMAN
% Der Stil wird zusätzlich zu \Lkeyword{OptComp} auf Komponenten angewendet,
% die als \Lkeyword{optional} markiert sind.
% \fi
% \ifENGLISH
% This style is applied to components marked as \Lkeyword{optional} in addition
% to \Lkeyword{OptComp}.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{optional}}]
\begin{pspicture}(3,1.5)
\lens[optional, beam](0,1)(3,1)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \ifGERMAN
% \Lstyle{OptionalStyle} wird nach \Lstyle{OptComp} angewendet, so dass
% einzelne Einstellungen überschrieben werden können.
% \fi
% \ifENGLISH
% \Lstyle{OptionalStyle} is applied after \Lstyle{OptComp} so that it
% can overwrite the general settings.
% \fi
%
% \iffalse
%<*ignore>
% \fi
\ifGERMAN
\begin{LTXexample}[morekeywords={[21]{OptComp, OptionalStyle, optional}}]
\begin{pspicture}(3,1.5)
\addtopsstyle{OptComp}{linewidth=3\pslinewidth, linecolor=red}
\newpsstyle{OptionalStyle}{linecolor=blue}
\lens(0,1)(2,1)
% Liniefarbe wird ueberschrieben, die Linienbreite nicht.
\lens[optional](0,1)(3,1)
\end{pspicture}
\end{LTXexample}
\fi\ifENGLISH
\begin{LTXexample}[morekeywords={[21]{OptComp, OptionalStyle, optional}}]
\begin{pspicture}(3,1.5)
\addtopsstyle{OptComp}{linewidth=3\pslinewidth, linecolor=red}
\newpsstyle{OptionalStyle}{linecolor=blue}
\lens(0,1)(2,1)
% linecolor overwritten, linewidth kept
\lens[optional](0,1)(3,1)
\end{pspicture}
\end{LTXexample}
\fi
% \iffalse
%</ignore>
% \fi
%
% \styleitem[linewidth=0.8\cs{pslinewidth}, arrowinset=0, arrowscale=0.8, arrows=<->]{VariableStyle} 
% \ifGERMAN Der Stil der Pfeile für verstellbare Komponenten (\Lcs{mirror} und
% \Lcs{optgrating}).
% \fi
% \ifENGLISH The style of the arrows of variable components (\Lcs{mirror} and
% \Lcs{optgrating}).
% \fi
% \end{stylelist}
%
% \begin{optionlist}
% \valitem{addtoOptComp}{list} 
% \addtostylemsg{OptComp}
%
% \valitem{newOptComp}{list}
% \newstylemsg{OptComp}
%
% \iffalse
%<*ignore>
% \fi
\ifGERMAN
\begin{LTXexample}[morekeywords={[21]{addtoOptComp,newOptComp}}]
\begin{pspicture}(3,1.5)
  \psset{beam}
  \newpsstyle{OptComp}{linewidth=3\pslinewidth}
  \mirror[addtoOptComp={linestyle=dotted}](0.5,0)(0.5,1)(1.5,1)
  % Ueberschreibt linewidth-Einstellungen
  \mirror[newOptComp={linestyle=dotted}](1.5,1)(2.5,1)(2.5,0)
\end{pspicture}
\end{LTXexample}
\fi
\ifENGLISH
\begin{LTXexample}[morekeywords={[21]{addtoOptComp,newOptComp}}]
\begin{pspicture}(3,1.5)
  \psset{beam}
  \newpsstyle{OptComp}{linewidth=3\pslinewidth}
  \mirror[addtoOptComp={linestyle=dotted}](0.5,0)(0.5,1)(1.5,1)
  % overwrites the linewidth settings
  \mirror[newOptComp={linestyle=dotted}](1.5,1)(2.5,1)(2.5,0)
\end{pspicture}
\end{LTXexample}
\fi
% \iffalse
%</ignore>
% \fi
%
% \boolitem[false]{optional}
% \ifGERMAN
% Markiert eine Komponente als optional indem der Stil
% \Lstyle{OptionalStyle} angewendet wird.
% \fi
% \ifENGLISH
% Mark an object as optional by applying the \Lstyle{OptionalStyle} style.
% \fi
% \end{optionlist}
% 
% \ifGERMAN\chapter{Freistrahlkomponenten}\fi
% \ifENGLISH\chapter{Free-ray components}\fi
% \label{chap:freeraycomp}
%
% \ifGERMAN In diesem Kapitel werden alle Freistrahlkomponenten und deren
% Parameter beschrieben. Freistrahlkomponenten können, im Gegensatz zu
% Faserkomponenten, transmittive und reflektive Grenzflächen haben, die für
% Raytracing von Lichtstrahlen verwendet werden können. Es gibt zwei
% unterschiedliche Komponententypen: manche benötigen nur zwei Knoten um
% positioniert zu werden (\ref{cmd:lens}--\ref{cmd:polarization}), wohingegen
% z.B. Spiegel drei Knoten benötigen um korrekt ausgerichtet zu werden
% (\ref{cmd:mirror}--\ref{cmd:pentaprism}).
% \fi
% \ifENGLISH This chapter describes all free-ray components and their
% options. Free-ray components differ from fiber components in that they provide
% transmittive or reflective interfaces which can be used to raytrace
% beams. They are divided in two types: some components like lenses need only
% two nodes for positioning (\ref{cmd:lens}--\ref{cmd:polarization}), whereas
% e.g. mirrors require three nodes to determine the orientation
% (\ref{cmd:mirror}--\ref{cmd:pentaprism}).
% \fi
%
% \ifGERMAN\section{Linse}\fi
% \ifENGLISH\section{Lens}\fi
% \label{sec:lens}
%
% \begin{ltxsyntax}
% \dipoledesc{lens}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.5)
  \lens[beam](0,1)(3,1){L}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
%
% \ifENGLISH A lens is defined by its height and the radii of the input and
% output interfaces.
% \fi
% \ifGERMAN Eine Linse wird durch ihre Höhe und die beiden Radien der Eingangs-
% und Ausgangsflächen definiert.
% \fi
% 
% \begin{optionlist}
% \numitem[1]{lensheight} 
% \ifGERMAN Setzt die Höhe der Linse.\fi
% \ifENGLISH Set the height of the lens.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{lensheight}}]
\begin{pspicture}(3,1.5)
  \lens[beam](0,1)(3,1){L1}
  \lens[lensheight=0.5](2,1)(3,1){L2}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \numitem[1]{lensradiusleft} 
% \ifGERMAN
% Setzt den Radius der linken Linsengrenzfläche. Ein positiver Wert \prm{num}
% ist für eine konvexe, ein negativer für eine konkave Krümmung. Null ergibt
% eine ebene Fläche.
% \fi
% \ifENGLISH
% Set the left radius of the lens. A positive \prm{num} is for convex, a
% negative one for concave curvatures. Use zero for a plain surface.
% \fi
% 
% \numitem[1]{lensradiusright} 
% \ifGERMAN
% Das Gleiche wie \Lkeyword{lensradiusleft}, nur für die rechte Grenzfläche.
% \fi
% \ifENGLISH
% Same as \Lkeyword{lensradiusleft} but for the right surface.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{lensradiusleft, lensradiusright}}]
\begin{pspicture}(3,1.5)
  \psset{lensradiusright=0, beam}
  \lens[lensradiusleft=1](0,1)(1.5,1){$R > 0$}
  \lens[lensradiusleft=-1](1.5,1)(3,1){$R < 0$}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \optitem{lensradius}{\prm{left}[ \prm{right}]}
% \ifGERMAN
% Setzt die linke und rechte Linsenkrümmung. Wird nur ein Wert angegeben, so
% wird dieser für beide Krümmungen verwendet.
% \fi
% \ifENGLISH
% Set the left and right lens curvatures. If only a single value is given, it is
% used for both curvatures.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{lensradius}}]
\begin{pspicture}(3,1.5)
  \lens[lensradius=-2, beam](0,1)(3,1)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \numitem[0]{lenswidth}
% \ifGERMAN
% Üblicherweise werden nur die Höhe und die beiden Radien für die
% Konstruktion der Linse verwendet, die Mittenbreite wird automatisch
% berechnet. Wenn \Lkeyword{lenswidth} auf einen Wert größer Null gesetzt wird,
% wird diese Breite verwendet. Das ist nur sinnvoll, wenn dicke Linsen
% gezeichnet werden sollen, da es andernfalls für zu kleine Werte zu unschönen
% Ergebnissen führt.
% \fi
% \ifENGLISH
% Usually only the height and the two radii are used to construct the lens,
% the width is calculated automatically. For \Lkeyword{lenswidth} greater
% than zero, this width is used instead. This is only useful if you want to draw
% thick lenses and it can give ugly results if the value is choosen too
% small.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{lenswidth}}]
\begin{pspicture}(3,2)
  \lens[lenswidth=0.5, beam](0,1)(2,1){thicklens}
  \lens[lenswidth=0.1, beam](2,1)(3,1)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \optitem{lens}{\prm{radiusleft}[ \prm{radiusright}[ \prm{height}[ \prm{width}]]]}
% \ifGERMAN
% Eine Option zum gleichzeitigen Setzen mehrerer Linsenparameter. Werte
% mittendrin können mit einem Punkt übersprungen und Werte am Ende können
% weggelassen werden (z.B. \opt{lens=. 1 1}).
% \fi
% \ifENGLISH
% A convenience option to specify all lens parameters with a single
% option. Intermediate values can be skipped with a dot, values at the end can
% be omitted (e.g. \opt{lens=.\ 1 1}).
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.5)
  \lens[lens=1](0,1)(1,1){L1}
  \lens[lensradius=-2 1, beam](0,1)(3,1){L2}
  \lens[lens=2 -0.7 1.2](2,1)(3,1){L3}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \boolitem[false]{thicklens}
% \ifENGLISH 
% This option was necessary until version 2.1 in order to draw a thick lens of
% width \Lkeyword{lenswidth} instead of using the calculated lens width. This
% option is superfluous since version 3.0 because setting \Lkeyword{lenswidth}
% to a positive value automatically draws a thick lens.
% \fi
% \ifGERMAN 
% Diese Option was bis Version 2.1 notwendig um dicke Linsen der Breite
% \Lkeyword{lenswidth} zu zeichnen, anstatt die berechnete Breite zu
% verwenden. Seit Version 3.0 ist diese Option überflüssig, da dicke Linsen
% gezeichnet werden, sobald \Lkeyword{lenswidth} auf einen positiven Wert
% gesetzt wird.
% \fi
% \end{optionlist}
% 
% \ifGERMAN\section{Optisches Plättchen}\fi
% \ifENGLISH\section{Optical plate}\fi
% 
% \begin{ltxsyntax}
% \dipoledesc{optplate}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.5)
  \optplate[beam](0,1)(3,1){filter}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% \begin{optionlist}
%   \numitem[1]{plateheight} 
%   \ifGERMAN Die Höhe des Plättchens.\fi
%    \ifENGLISH The height of the plate.\fi
% 
%   \optitem[2\nxLcs{pslinewidth}]{platelinewidth}{\prm{num} or \prm{dimen}} 
%   \ifGERMAN \linewidthexplanation{des Plättchens}{Plättchen}\fi
%   \ifENGLISH \linewidthexplanation{plate}{plates}\fi
% \end{optionlist}
% 
% \ifGERMAN\section{Verzögerungsplättchen}\fi
% \ifENGLISH\section{Retardation plate}\fi
%
% \begin{ltxsyntax}
% \dipoledesc{optretplate}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.5)
  \optretplate[beam](0,1)(3,1){$\nicefrac{\lambda}{2}$}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% 
% \begin{optionlist}
% \numitem*[1]{plateheight}
% \ifGERMAN Die Höhe des Plättchens.\fi
% \ifENGLISH The height of the plate.\fi
%
% \numitem[0.1]{platewidth}
% \ifGERMAN Die Breite des Plättchens.\fi
% \ifENGLISH The width of the plate.\fi
%
% \optitem{platesize}{\prm{width} \prm{height}}
% \ifGERMAN Die Breite und Höhe des Plättchens, äquivalent zum Aufruf von
% \Lkeyword{platewidth} und \Lkeyword{plateheight}.
% \fi
% \ifENGLISH The width and height of the plate, is equivalent to calling both
% \Lkeyword{platewidth} and \Lkeyword{plateheight}.
% \fi
% \end{optionlist}
% 
% \ifGERMAN\section{Lochblende}\fi
% \ifENGLISH\section{Pinhole}\fi
% 
% \begin{ltxsyntax}
% \dipoledesc{pinhole}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.5)
  \pinhole[beam](0,1)(3,1){PH}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% 
% \begin{optionlist}
% \numitem[1]{outerheight}
% \ifGERMAN Die Gesamthöhe der Lochblende.\fi
% \ifENGLISH The total height of the pinhole.\fi
%
% \numitem[0.1]{innerheight}
% \ifGERMAN Die Höhe des Lochs.\fi
% \ifENGLISH The height of the hole.\fi
%
% \optitem[2\nxLcs{pslinewidth}]{phlinewidth}{\prm{num} or \prm{dimen}}
% \ifGERMAN \linewidthexplanation{der Lochblende}{Lochblenden}\fi
% \ifENGLISH \linewidthexplanation{pinhole}{pinholes}\fi
% 
% \numitem[0]{phwidth} 
% \ifGERMAN 
% Die Lochblende wird plastischer gezeichnet, falls \Lkeyword{phwidth}
% ungleich Null ist. In diesem Fall wird \Lkeyword{phlinewidth} ignoriert. Bei
% einem negativen Wert wird die Form gespiegelt.
% \fi
% \ifENGLISH
% The pinhole is drawn in a more plastic style if \Lkeyword{phwidth} is
% not zero, in this case the \Lkeyword{phlinewidth} is ignored. For negative
% values the shape is mirrored.
% \fi 
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{phwidth}}]
\begin{pspicture}(3,1.5)
  \pinhole[beam, phwidth=-0.1](0,1)(1.5,1){neg}
  \pinhole[beam, phwidth=0.2](1.5,1)(3,1){pos}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
% 
%
% \ifGERMAN\section{Box}\fi
% \ifENGLISH\section{Box}\fi
% 
% \begin{ltxsyntax}
% \dipoledesc{optbox}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
  \optbox[beam](0,0)(3,2){box}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% 
% \begin{optionlist}
% \numitem[1.4]{optboxwidth}
% \ifGERMAN Die Breite der Box.\fi
% \ifENGLISH The width of the box.\fi
%
% \numitem[0.8]{optboxheight}
% \ifGERMAN Die Höhe der Box.\fi
% \ifENGLISH The height of the box.\fi
%
% \optitem{optboxsize}{\prm{width} \prm{height}}
% \ifGERMAN Die Breite und Höhe der Box, äquivalent zum Aufruf von
% \Lkeyword{optboxwidth} und \Lkeyword{optboxheight}.
% \fi
% \ifENGLISH The width and height of the box, is equivalent to calling both
% \Lkeyword{optboxwidth} and \Lkeyword{optboxheight}.
% \fi
% \end{optionlist}
%
%
% \ifGERMAN\section{Kristall}\fi
% \ifENGLISH\section{Crystal}\fi
%
% \begin{ltxsyntax}
% \dipoledesc{crystal}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.3)
  \crystal[beam](0,1)(3,1){Crystal}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% 
% \begin{optionlist}
% \numitem[1.4]{crystalwidth}
% \ifGERMAN Die Breite des Kristalls.\fi
% \ifENGLISH The width of the crystal.\fi
%
% \numitem[0.6]{crystalheight}
% \ifGERMAN Die Höhe des Kristalls.\fi
% \ifENGLISH The height of the crystal.\fi
%
% \optitem{crystalsize}{\prm{width} \prm{height}}
% \ifGERMAN Die Breite und Höhe des Kristalls, äquivalent zum Aufruf von
% \Lkeyword{crystalwidth} und \Lkeyword{crystalheight}.
% \fi
% \ifENGLISH The width and height of the crystal, is equivalent to calling both
% \Lkeyword{crystalwidth} and \Lkeyword{crystalheight}.
% \fi
%
% \numitem[0.3]{caxislength}
% \ifGERMAN Die zusätzliche Länge des Pfeils für die $c$-Achse, wird weggelassen
% falls die Länge \opt{0} ist und gespiegelt falls der Wert negativ ist. Die
% Gesamtlänge ist \Lkeyword{caxislength} plus \Lkeyword{crystalheight}.
% \fi
% \ifENGLISH The additional length of the $c$-axis, is dropped when set to
% \opt{0} and is mirrored if the values is negative. The total length is
% \Lkeyword{caxislength} plus \Lkeyword{crystalheight}.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{caxislength}}]
\begin{pspicture}(0,0.4)(3,1.5)
  \psset{crystalsize=0.5 0.8, label=-45 . l}
  \crystal[position=0.2, caxislength=0.5](0,1)(3,1){pos}
  \crystal[beam, caxislength=0](0,1)(3,1){0}
  \crystal[position=0.8, caxislength=-0.5](0,1)(3,1){neg}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \boolitem[false]{caxisinv}
% \ifGERMAN 
% Invertiert die Richtung der $c$-Achse, ist äquivalent zu einem
% Vorzeichenwechsel von \Lkeyword{caxislength}.
% \fi
% \ifENGLISH 
% Invert the direction of the $c$-axis, this is equivalent to changing the sign
% of \Lkeyword{caxislength}.
% \fi
%
% \boolitem[false]{voltage}
% \ifGERMAN Zeichnet einen Spannungsanschluss und ein Erdungszeichen.\fi
% \ifENGLISH Draw a voltage connection and a ground symbol.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{voltage}}]
\begin{pspicture}(0,0.4)(3,1.5)
  \crystal[voltage, beam](0,1)(3,1)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \boolitem[false]{lamp}
% \ifGERMAN Zeichnet eine Lampe neben den Kristall.\fi
% \ifENGLISH Draw a lamp near the crystal.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{lamp}}]
\begin{pspicture}(0,0.4)(3,1.7)
  \crystal[lamp, beam](0,1)(3,1)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \numitem{lampscale}
% \ifGERMAN Skalierung der Lampe.\fi
% \ifENGLISH Scaling of the lamp.\fi
% \deprecatedmsg{\ifGERMAN den Stil \fi\ifENGLISH style \fi\Lstyle{CrystalLamp}}
% \end{optionlist}
%
% \begin{stylelist}
% \styleitem[linewidth=0.7\cs{pslinewidth}, linestyle=dashed, dash=2pt 2pt, arrowinset=0, arrows=->]{CrystalCaxis}
% \ifGERMAN Der Stil für die $c$-Achse inklusive der Pfeilart.\fi
% \ifENGLISH The style of the $c$-axis including the arrow type.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{CrysalCaxis}}]
\begin{pspicture}(0,0.5)(3,1.6)
  \newpsstyle{CrystalCaxis}{linecolor=red, arrows=->>}
  \crystal[beam](0,1)(3,1)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \styleitem[linewidth=0.6\cs{pslinewidth}]{CrystalLamp}
% \ifGERMAN Der Stil für die Hintergrundlampe.\fi
% \ifENGLISH The style of the crystal background lamp.\fi
% \end{stylelist}
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{voltage, lamp}}]
\begin{pspicture}(3,1.7)
  \crystal[fillstyle=solid, fillcolor=yellow!90!black, 
             label=1.2 -45, voltage, 
             lamp, beam](0,1)(3,1){SBN:Ce}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \ifGERMAN\section{Detektor}\fi
% \ifENGLISH\section{Detector}\fi
% 
% \begin{ltxsyntax}
% \dipoledesc{optdetector}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.2)
  \optdetector[beam](0,0)(1.5,1){detector}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
%
% \ifENGLISH The detector is always placed at the end of the reference line
% (\Lkeyword{position}\opt{=end}). This setting cannot be changed.
% \fi
% \ifGERMAN Der Detektor wird immer ans Ende der Referenzlinie platziert
% (\Lkeyword{position}\opt{=end}). Diese Einstellung kann nicht verändert
% werden.
% \fi
% 
% \begin{optionlist}
% \optitem[0.8]{detsize}{\prm{num} or \prm{width} \prm{height}}
% \ifGERMAN 
% Wenn eine einzelne Zahl angegeben ist, dann ist das die Seitenlänge
% (\opt{diode}) bzw. der Durchmesser (\opt{round}) des Detektors. Werden zwei
% Zahlen angegeben, so sind das Breite und Höhe des Detektors. Beachten Sie,
% dass \opt{detsize=1} und \opt{detsize=1 1} für \opt{dettype=round} nicht dasselbe ist.
% \fi
% \ifENGLISH 
% If a single number is given it is the side length (\opt{diode}) or the
% diameter (\opt{round}) of the detector. Two numbers define the width and
% height of the detector. Note, that \opt{detsize=1} and \opt{detsize=1 1} are
% not equivalent for \opt{dettype=round}.
% \fi
% 
% \choitem[round]{dettype}{round, diode} 
% \ifGERMAN
% Dieser Parameter bestimmt den Typ und damit das Aussehen des Detektors.
% \fi
% \ifENGLISH
% This parameter selects between different types of detectors.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{dettype}}] 
\begin{pspicture}(3,1.5)
  \optdetector[beam, dettype=diode](0,0)(1.5,1){detector}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
%
% \begin{stylelist}
% \styleitem{DetectorStyle} 
% \ifGERMAN 
% Der Stil der Diode für \Lkeyword{dettype}\opt{=diode}.
% \fi
% \ifENGLISH 
% The style of the diode for \Lkeyword{dettype}\opt{=diode}.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.5)
  \newpsstyle{OptComp}{linewidth=2\pslinewidth}
  \newpsstyle{DetectorStyle}{linewidth=0.5\pslinewidth}
  \optdetector[dettype=diode](0,1)(2,1)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{stylelist}
% 
% \ifGERMAN\section{Optische Diode}\fi
% \ifENGLISH\section{Optical diode}\fi
%
% \begin{ltxsyntax}
% \dipoledesc{optdiode}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{optdiode}}] 
\begin{pspicture}(3,2)
  \optdiode[beam](0,1)(3,1){Diode}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
%
% \ifENGLISH The optical diode has a default setting of
% \Lkeyword{allowbeaminside}\opt{=false}.
% \fi
% \ifGERMAN Die optische Diode hat die Voreinstellung
% \Lkeyword{allowbeaminside}\opt{=false}.
% \fi
%
% \begin{optionlist}
% \numitem[0.8]{optdiodesize}
% \ifGERMAN 
% Die Seitenlänge der optischen Diode.
% \fi
% \ifENGLISH
% The side length of the optical diode.
% \fi
% \end{optionlist}
% 
% \ifGERMAN\section{Doveprisma}\fi
% \ifENGLISH\section{Dove prism}\fi
% 
% \begin{ltxsyntax}
% \dipoledesc{doveprism}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{doveprism}}] 
\begin{pspicture}(3,1.5)
  \doveprism[beam](0,1)(3,1){Dove}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% 
% \begin{optionlist}
% \optitem[0.6]{doveprismsize}{\prm{num} or \prm{width} \prm{height}}
% \ifGERMAN
% Wenn eine Zahl angegeben ist, dann ist das die Höhe des Prismas, die
% Gesamtbreite beträgt das dreifache. Zwei Zahlen geben Breite und Höhe des
% Doveprisma an. Die Winkel an der Eingangs- und Ausgangsfläche betragen immer
% 45\textdegree.
% \fi
% \ifENGLISH
% A single number defines the height of the prism, the total width is set to
% three times the height. Two number define the width and height of the dove
% prism. The angles at the input and output faces are always 45\textdegree.
% \fi
% \end{optionlist}
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{doveprism}}] 
\begin{pspicture}(4,1.5)
  \optplane(0,1)
  \doveprism[doveprismsize=1.2](0,1)(4,1)
  \optplane(4,1)
  \drawbeam[raytrace=false, linecolor=black]{-}
  \drawbeam[n=1.5, linecolor=red]{-}
  \drawbeam[n=*sqrt(5), linecolor=green, linestyle=dashed]{-}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \ifGERMAN\section{Glan--Thompson prism}\fi
% \ifENGLISH\section{Glan-Thompson-Prisma}\fi
% 
% \begin{ltxsyntax}
% \dipoledesc{glanthompson}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{glanthompson}}] 
\begin{pspicture}(3,1.5)
  \glanthompson[beam](0,1)(3,1){Glan-Thompson}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% 
% \begin{optionlist}
% \numitem[1.0]{glanthompsonwidth}
% \ifGERMAN Die Breite des Prisma.\fi
% \ifENGLISH The width of the prism.\fi
%
% \numitem[0.5]{glanthompsonheight}
% \ifGERMAN Die Höhe des Prisma.\fi
% \ifENGLISH The height of the prism.\fi
%
% \optitem{glanthompsonsize}{\prm{width} \prm{height}}
% \ifGERMAN Die Breite und Höhe des Prisma, äquivalent zum Aufruf von
% \Lkeyword{glanthompsonwidth} und \Lkeyword{glanthompsonheight}.
% \fi
% \ifENGLISH The width and height of the prism, is equivalent to calling both
% \Lkeyword{glanthompsonwidth} and \Lkeyword{glanthompsonheight}.
% \fi
%
% \numitem[0]{glanthompsongap}
% \ifGERMAN 
% Der Abstand der beiden Teilprismen in $x$-Richtung, die Linienbreiten
% werden nicht berücksichtigt. Die Gesamtbreite ist von diesem Wert
% unabhängig, aber der Winkel der reflektierenden Fläche wird davon beeinflusst.
% \fi
% \ifENGLISH The separation of the two prisms in $x$-direction. The
% total width does not depend on this value, but the angle of the
% reflective plane is affected.
% \fi
% 
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1)
  \glanthompson[glanthompsongap=0.1, beam](0,0.5)(3,0.5)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
%
% \ifGERMAN Von der Implementierung entspricht das Glan-Thompson-Prisma
% für \Lkeyword{glanthompsongap}\opt{=0} einem Strahlteiler, der nur
% zwei Knoten zur Positionierung benötigt und nicht quadratisch ist.
%
% Beachten Sie, dass das Prisma für \Lkeyword{glanthompsongap}\opt{>\,0}
% nicht von beiden Seiten gleich verwendet werden kann, da in der
% derzeitigen Implementierung nur eine uneindeutige Grenzfläche
% (reflektierend oder transmittierend) zugelassen ist. In dem folgenden
% Beispiel sieht man, dass der rote Strahl an der falsche Fläche
% reflektiert wird.
% \fi
% \ifENGLISH
% The implementation of the Glan--Thompson prism for
% \Lkeyword{glanthompsongap}\opt{=0} is equivalent to a beamsplitter
% which is positioned with two nodes only and which is not quadratic.
%
% Please note, that the Prism cannot be used properly from both sides
% for \Lkeyword{glanthompsongap}\opt{>\,0} because the current
% implementation allows only a single ambiguous interface (reflective or
% transmittive). In the following example you see, that the red beam is
% reflected at the wrong interface.
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(4,2)
  \pnode(0,1){A}\pnode(4,1){B}
  \glanthompson[glanthompsongap=0.2, glanthompsonsize=2 1](A)(B)
  \optplane[angle=90](2,0)\optplane[angle=90](2,2)
  \addtopsstyle{Beam}{ArrowInside=->, arrowscale=1.5}
  \drawbeam[beampos=0.1](A){1-2}
  \drawbeam[beampos=0.1, linecolor=red](B){1}{3}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN \prettyref{ex:glan-thompson} enthält ein weiterführendes
% Beispiel mit einem Glan-Thompson-Prisma.\fi
% \ifENGLISH \prettyref{ex:glan-thompson} shows a further setup with a
% Glan--Thompson prism.\fi
%
% \ifGERMAN\section{Polarisation}\fi
% \ifENGLISH\section{Polarization}\fi
%
% \begin{ltxsyntax}
% \dipoledesc{polarization}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{polarization}}] 
\begin{pspicture}(3,1)
  \polarization[beam](0,0.5)(3,0.5)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% \begin{optionlist}
% \numitem[0.6]{polsize}
% \ifGERMAN Die Größe des Polarisationszeichens, der Kreis für \opt{perp} und
% \opt{polmisc} ist halb so groß.
% \fi
% \ifENGLISH The size of the polarization symbol, the circle for \opt{perp} and
% \opt{polmisc} is half of this.
% \fi
%
% \optitem[0.7\nxLcs{pslinewidth}]{pollinewidth}{\prm{num} or \prm{dimen}}
% \ifGERMAN \linewidthexplanation{des Polarisationszeichens}{Polarisationszeichen}\fi
% \ifENGLISH \linewidthexplanation{polarisation sign}{polarisation signs}\fi
% \deprecatedmsg{\ifGERMAN den Stil \fi\ifENGLISH style \fi\Lstyle{Polarization}}
%
% \choitem[parallel]{poltype}{parallel, perp, misc, lcirc, rcirc}
% \ifGERMAN Dieser Parameter wählt die Polarizationsart aus.\fi
% \ifENGLISH This parameter choses the polarization type.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{poltype}}] 
\begin{pspicture}(0,-0.3)(3,4.3)
  \psset[optexp]{beam}
  \begin{optexp}
  \polarization[poltype=parallel, abspos=0.5](0,4)(3,4)
  \polarization[poltype=perp, abspos=1](0,3)(3,3)
  \polarization[poltype=misc, abspos=1.5](0,2)(3,2)
  \polarization[poltype=lcirc, abspos=2](0,1)(3,1)
  \polarization[poltype=rcirc, abspos=2.5](0,0)(3,0)
  \end{optexp}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
%
% \begin{stylelist}
% \styleitem[arrowscale=0.8, linewidth=\cs{pslinewidth}, dotsize=3\cs{pslinewidth}]{Polarization}
% \ifGERMAN Bestimmt das Aussehen der Polarisationssymbole.\fi
% \ifENGLISH Affects the style of the polarisation symbols.\fi
% \end{stylelist}
% 
% \ifGERMAN\section{Spiegel}\fi
% \ifENGLISH\section{Mirror}\fi
% 
% \begin{ltxsyntax}
% \tripoledesc{mirror}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
  \mirror[beam](0,0)(1.8,1.5)(0,2){M}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% 
% \begin{optionlist}
% \numitem[1]{mirrorwidth}
% \ifGERMAN Die Breite des Spiegels.\fi
% \ifENGLISH The width of the mirror.\fi
% 
% \optitem[2\nxLcs{pslinewidth}]{mirrorlinewidth}{\prm{num} or \prm{dimen}} 
% \ifGERMAN \linewidthexplanation{des Spiegels}{Spiegel}\fi
% \ifENGLISH \linewidthexplanation{mirror}{mirrors}\fi
%
% \optitem[0]{mirrorradius}{\prm{radius}[ 0]} 
% \ifGERMAN
% Diese Parameter setzt die Krümmung des Spiegels. Null ergibt einen
% ebenen, ein negativer Radius einen konvexen und ein positiver Radius
% einen konkaven Spiegel.
% \fi
% \ifENGLISH
% This parameter defines the curvature of the mirror. A value of \opt{0}
% is for a plain mirror, a negative radius for a convex mirror and a
% positive radius gives you a concave mirror.
% \fi
% 
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{mirrorradius}}]
\begin{pspicture}(3,3)
  \psset[optexp]{labeloffset=0.5}
  \mirror[mirrorradius=1](0,0)(1,2)(1.8,1){convex}
  \mirror[mirrorradius=-1](1,2)(1.8,1)(2.5,3){concave}
  \drawbeam(0,0){-}(2.5,3)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN Wird kein zweiter Wert angegeben, so ist die Krümmung der
% zweiten Fläche eines \opt{extended} oder \opt{semitrans} Spiegels die
% Gleiche wie bei der Hauptgrenzfläche (siehe vorheriges Beispiel). Wird
% die Null als zweiter Wert angegeben (andere Werte werden nicht
% unterstützt), so ist die zweite Fläche flach:
% \fi
% \ifENGLISH If no second value is specified, the curvature of the
% second interface of an \opt{extended} or \opt{semitrans} mirror is the
% same as that of the main interface (see previous example). If zero is
% given as second value (other values are not supported), the second
% interface is plain.
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{mirrorradius}}]
\begin{pspicture}(3,3)
  \mirror[mirrorradius=1 0, mirrortype=semitrans](0,0)(1,2)(1.8,1){convex}
  \mirror[mirrorradius=-1 0, mirrortype=extended](1,2)(1.8,1)(2.5,3){concave}
  \drawbeam(0,0){-}(2.5,3)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN Die Angabe von \Lkeyword{mirrordepth} bezieht sich immer auf
% die Mindesttiefe des Spiegels.
% \fi
% \ifENGLISH The value of \Lkeyword{mirrordepth} always refers to the
% minimum depth of the mirror.
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{mirrorradius, mirrordepth}}]
\begin{pspicture}(3,3)
  \psset[optexp]{mirrordepth=0.2}
  \mirror[mirrorradius=1 0, mirrortype=semitrans](0,0)(1,2)(1.8,1){convex}
  \mirror[mirrorradius=-1 0, mirrortype=extended](1,2)(1.8,1)(2.5,3){concave}
  \drawbeam(0,0){-}(2.5,3)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \choitem[plain]{mirrortype}{plain, piezo, extended, semitrans}
% \ifGERMAN
% Diese Parameter wählt die Spiegelart aus. Das Aussehen wird mit
% \Lstyle{PiezoMirror}, \Lstyle{ExtendedMirror} und \Lstyle{SemitransMirror}
% gesteuert.
% \fi
% \ifENGLISH
% The \nxLkeyword{mirrortype} selects between different types of mirrors. The
% style is controlled with \Lstyle{PiezoMirror}, \Lstyle{ExtendedMirror}, and
% \Lstyle{SemitransMirror}.
% \fi
% 
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{mirrortype}}]
\begin{pspicture}(3,2)
  \mirror[mirrortype=extended,
            beam](0,0)(1.8,1.5)(0,2){ext}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN Beachten Sie, dass der Anschlussdraht für den Piezospiegel nicht
% gezeichnet wird, falls \Lkeyword{extnode} verwendet wird.
% \fi
% \ifENGLISH Note, that the default piece of wire is omitted when using
% \Lkeyword{extnode} with a piezo mirror.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{mirrortype}}]
\begin{pspicture}(3,2)
\mirror[mirrortype=piezo,
          beam](0,0)(1.8,1.5)(0,2){piezo}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN Ein halbdurchlässiger Spiegel (\opt{semitrans}) hat, im Gegensatz zu
% den anderen Spiegeltypen, zwei Grenzflächen, deren Abstand und Position vom
% Wert und Vorzeichen von \Lkeyword{mirrordepth} abhängt.
% \fi
% \ifENGLISH A semi-transparent mirror (\opt{semitrans}) has two interfaces, in
% contrast to the other mirror types. Their distance and position depends on the
% value and sign of \Lkeyword{mirrordepth}.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{mirrortype, mirrordepth}}]
\psset{unit=1.5}
\begin{pspicture}(2,2)
  \mirror[mirrortype=semitrans](0,1)(1,1)(1,0)
  \drawbeam(0,1){}(1,0)
  \drawbeam[linecolor=red](2,1){}(1,2)
  \drawbeam[beampos=0.05, linecolor=blue](0,1){}(2,1)
\end{pspicture}
\end{LTXexample}

\begin{LTXexample}[morekeywords={[21]{mirrortype, mirrordepth}}]
\psset{unit=1.5}
\begin{pspicture}(2,2)
  \mirror[mirrortype=semitrans, mirrordepth=-0.15](0,1)(1,1)(1,0)
  \drawbeam(0,1){}(1,0)
  \drawbeam[linecolor=red](2,1){}(1,2)
  \drawbeam[beampos=0.05, linecolor=blue](0,1){}(2,1)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN Eine negative Spiegeltiefe \Lkeyword{mirrordepth} ist
% äquivalent zu einer positiven Tiefe kombiniert mit
% \Lkeyword{angle}\opt{=180}.
% \fi
% \ifENGLISH A negative \Lkeyword{mirrordepth} is equivalent to a
% positive depth combined with \Lkeyword{angle}\opt{=180}. 
% \fi
% 
% \boolitem[false]{variable}
% \ifGERMAN
% Zeichnet einen verstellbaren Spiegel, der mit zwei zusätzlichen gekrümmten
% Pfeilen an beiden Seiten angedeutet wird. Das Aussehen, inklusive der Pfeile,
% wird von \Lstyle{VariableStyle} vorgegeben.
% \fi
% \ifENGLISH
% Draw an adjustable mirror which has two additional curved arrows on both
% sides. The appearance including the arrow types is determined by
% \Lstyle{VariableStyle}.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{variable}}]
\begin{pspicture}(3,2)
  \mirror[beam, variable](0,0)(1.8,1.5)(0,2){var}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \numitem[0.1]{mirrordepth} 
% \ifGERMAN Die Gesamttiefe eines breiten Spiegels.\fi
% \ifENGLISH The total depth of an extended mirror.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{mirrortype, mirrordepth}}]
\begin{pspicture}(3,2)
  \mirror[mirrortype=extended, mirrordepth=0.2,
            beam](0,0)(1.8,1.5)(0,2)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
%
% \begin{stylelist}
% \styleitem[linestyle=none, hatchwidth=0.5\cs{pslinewidth}, hatchsep=1.4\cs{pslinewidth}, fillstyle=hlines]{ExtendedMirror} 
% \ifGERMAN Der Stil für den \opt{extended} Spiegel.\fi
% \ifENGLISH The style for the \opt{extended} mirror.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{mirrortype, ExtendedMirror}}]
\begin{pspicture}(3,2)
  \newpsstyle{ExtendedMirror}{fillstyle=solid, 
                                fillcolor=Gold,
                                linestyle=none}
  \mirror[mirrortype=extended,
            beam](0,0)(1.8,1.5)(0,2){ext}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \styleitem[fillstyle=solid, fillcolor=black!30]{PiezoMirror} 
% \ifGERMAN 
% Der Stil für den \opt{piezo} Spiegel. Dieser kann auch dazu verwendet
% werden, die Größe des Piezos zu verändern, wie in dem folgenden Beispiel zu sehen ist.
% \fi
% \ifENGLISH
% This style defines the appearance of the \opt{piezo} mirror. This can also
% be used to change the size of piezo part, as the example shows.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{mirrortype, PiezoMirror}}]
\begin{pspicture}(3,2)
  \addtopsstyle{PiezoMirror}{xunit=2}
  \mirror[mirrortype=piezo,
            beam](0,0)(1.8,1.5)(0,2){piezo}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \styleitem[linestyle=none, fillstyle=solid, fillcolor=black!30]{SemitransMirror} 
% \ifGERMAN 
% Der Stil für den \opt{semitrans} Spiegel.
% \fi
% \ifENGLISH
% This style defines the appearance of the \opt{semitrans} mirror.
% \fi
% \end{stylelist}
% 
% \ifGERMAN\section{Strahlteiler}\fi
% \ifENGLISH\section{Beamsplitter}\fi
%
% \begin{ltxsyntax}
% \tripoledesc{beamsplitter}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
  \beamsplitter[beam](0,1)(2,1)(2,0){BS}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% 
% \begin{optionlist}
% \numitem[0.8]{bssize}
% \ifGERMAN Die Größe des Strahlteilers.\fi
% \ifENGLISH The beamsplitter size.\fi
%  
% \choitem[cube]{bsstyle}{cube, plate} 
% \ifGERMAN
% Wählt zwischen zwei Strahlteilertypen: einem Strahlteilerwürfel (\opt{cube})
% und einem halbdurchlässigen Spiegel (\opt{plate}). Dieser halbdurchlässige
% Spiegel ist äquivalent zu \Lcs{mirror} mit
% \Lkeyword{mirrortype}\opt{=semitrans} für \Lkeyword{mirrordepth}\opt{=0}.
% \fi
% \ifENGLISH
% Selects between two types of beamsplitters: the beamsplitter cube (\opt{cube})
% and the semitransparent mirror (\opt{plate}).  This semitransparent mirror ist
% equivalent to \Lcs{mirror} with \Lkeyword{mirrortype}\opt{=semitrans} and
% \Lkeyword{mirrordepth}\opt{=0}.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{bsstyle}}]
\begin{pspicture}(3,2)
  \beamsplitter[bsstyle=plate, beam](0,1)(2,1)(2,0){BS}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
% 
% \ifGERMAN\section{Optisches Gitter}\fi
% \ifENGLISH\section{Optical grating}\fi
% 
% \begin{ltxsyntax}
% \tripoledesc{optgrating}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
  \optgrating[beam](0,2)(1.8,1.5)(0,0){grating}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
%
% \ifENGLISH Before package version 3.0 this component was called
% \Lcs*{optgrid}. Since then this command name is deprecated and will be removed
% in future versions.
% \fi
% \ifGERMAN Vor Paketversion 3.0 hieß diese Komponente \Lcs*{optgrid}. Seitdem
% ist diese Benennung veraltet und wird in zukünftigen Versionen entfernt
% werden.
% \fi
% \begin{optionlist}
% \numitem[1]{gratingwidth} 
% \ifGERMAN Die Breite des Gitters.\fi
% \ifENGLISH The width of the grating.\fi
% 
% \numitem[0.15]{gratingheight} 
% \ifGERMAN Die Gesamthöhe des Gitters.\fi
% \ifENGLISH The total height of the grating.\fi
% 
% \numitem[0.075]{gratingdepth}
% \ifGERMAN 
% Die absolute Modulationstiefe der Gitterstruktur. Die Gesamthöhe wird
% an diesen Wert angepasst falls sie kleiner als die Modulationtiefe ist, 
% andernfalls wird sie nicht beinflusst.
% \fi
% \ifENGLISH
% The modulation depth of the grating structure. The total height is
% adapted to this value if it is smaller than the modulation
% depth. Otherwise the total height is not affected.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{gratingdepth}}]
\begin{pspicture}(3,2)
  \optgrating[gratingdepth=0.05, 
                beam](0,2)(1.8,1.5)(0,0){grating}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \intitem[10]{gratingcount} 
% \ifGERMAN Die Anzahl der Gitterlinien.\fi
% \ifENGLISH The number of grating grooves.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{gratingcount}}]
\begin{pspicture}(3,2)
  \optgrating[gratingcount=3, 
                beam](0,2)(1.8,1.5)(0,0){grating}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \choitem[blazed]{gratingtype}{blazed, binary} 
% \ifGERMAN 
% Wählt zwischen einem binären Gitter (\opt{binary}) und einem Blazegitter
% (\opt{blazed}).
% \fi
% \ifENGLISH
% Select between a \opt{binary} and a \opt{blazed} grating.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{gratingtype}}]
\begin{pspicture}(3,2)
  \optgrating[gratingtype=binary, 
                beam](0,2)(1.8,1.5)(0,0){grating}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \choitem[top]{gratingalign}{t, top, c, center} 
% \ifGERMAN 
% Wählt, ob die Reflektionsebene auf den Gitterspitzen (\opt{top}), oder
% in der Mitte des Gitters (\opt{center}) liegt. Wählt man \opt{center}
% aus, macht es Sinn die \Lenv{optexp}-Umgebung oder eine
% halbtransparente Strahlfüllung zu verwenden.
% \fi
% \ifENGLISH
% Selects if the reflection plane resides on \opt{top} of the grating or
% in its \opt{center}. If you choose \opt{center}, you should use the
% \Lenv{optexp} environment or a semitransparent beam filling. 
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{gratingalign}}]
\begin{pspicture}(3,2)
\pnode(0.5,0){A}\pnode(0.5,1.5){B}\pnode(2,1.5){C}\pnode(2,0){D}
\psset{unit=1.5, labeloffset=0.4}
\begin{optexp}
  \optgrating[gratingalign=top](A)(B)(C){top}
  \optgrating[gratingalign=center](B)(C)(D){center}
  \drawwidebeam[fillstyle=solid, fillcolor=green!50, beamwidth=0.5](A){-}(D)
\end{optexp}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \boolitem[false]{reverse} 
% \ifGERMAN
%   Invertiert die Steigung des Blazegitters.
% \fi
% \ifENGLISH
%   Reverse the slope of the grooves of the \opt{blazed} grating.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{reverse}}]
\begin{pspicture}(3,2)
  \optgrating[reverse, beam](0,2)(1.8,1.5)(0,0){grating}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \optitem[0.7\nxLcs{pslinewidth}]{gratinglinewidth}{\prm{num} or \prm{dimen}} 
% \ifGERMAN \linewidthexplanation{des Gitters}{Gitter}\fi
% \ifENGLISH \linewidthexplanation{grating}{gratings}\fi
% \end{optionlist}
%
% \begin{stylelist}
% \item[\smash{%
%   \begin{tabular}[t]{@{}l@{}}
%     \Lkeyword*{optgridwidth}\\
%     \Lkeyword*{optgridheight}\\
%     \Lkeyword*{optgriddepth}\\
%     \Lkeyword*{optgridcount}\\
%     \Lkeyword*{optgridtype}\\
%     \Lkeyword*{optgridlinewidth}
%   \end{tabular}}]^^A
% \noindent
% \ifGERMAN Diese Parameter wurden in die entsprechenden \opt{grating*}
%   Parameter umbenannt und sind seit Version 3.0 veraltet.
% \fi
% \ifENGLISH These parameters were renamed to the respective \opt{grating*}
% parameters and are deprecated since version 3.0.
% \fi
% \vspace*{2cm}
% \end{stylelist}
% 
% \ifGERMAN\section{Prisma}\fi
% \ifENGLISH\section{Prism}\fi
% 
% \begin{ltxsyntax}
% \tripoledesc{optprism}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
  \optprism[beam](0,1)(2,1)(3,0){Prism}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% \ifGERMAN
% Das Prisma wird immer symmetrisch bezüglich der \prm{in} und \prm{out}
% Knoten ausgerichtet. Für asymmetrischen Strahlengang siehe
% \prettyref{chap:connecting}.
% \fi
% \ifENGLISH
% The prism is always placed symmetric between \prm{in} and \prm{out}
% nodes. For asymmetric beam traces see \prettyref{chap:connecting}.
% \fi
%
% \begin{optionlist}
% \numitem[1]{prismsize} 
% \ifGERMAN Die Höhe des Prismas.\fi
% \ifENGLISH The height of the prism.\fi
%
% \numitem[60]{prismangle}
% \ifGERMAN Der obere Winkel des Prismas.\fi
% \ifENGLISH The upper angle of the prism.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]prismangle}]
\begin{pspicture}(3,2)
  \optprism[prismangle=30, beam](0,1)(2,1)(3,0){Prism}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \choitem[auto]{prismalign}{auto,center}
% \ifENGLISH Sets the vertical alignment of the prism with respect to the
% «reflection» node \prm{center}. For \opt{auto}, the prism is shifted such,
% that the interface nodes lay on the connection between the respective
% reference node and the «reflection» node. If the value is \opt{center}, the
% «reflection» node coincides with the component center. See the following
% examples for further explanation.
% \fi
% \ifGERMAN Wählt die vertikale Ausrichtung des Prisma bezüglich des
% «Reflektionsknoten» \prm{center}. Ist der Wert \opt{auto}, so wird das Prisma
% so verschoben, dass die Grenzflächenknoten auf der Verbindungslinie zwischen
% dem entsprechenden Referenzknoten und dem «Reflektionsknoten» liegen. Für
% \opt{center} fällt der «Reflektionsknoten» mit der Komponentenmitte
% zusammen. Siehe die folgende Beispiele zur weiteren Erklärung.
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{pspicture}(13,3)
  \footnotesize
  \pnode(0,0){A}\pnode(3,1.8){B}\pnode(6,0){C}
  \psdot(A)\uput[90](A){\prm{in}}
  \psdot(B)\uput[90](B){\prm{center}}
  \psdot(C)\uput[90](C){\prm{out}}
  \optprism[prismsize=2](A)(B)(C)
  \psline[style=Refline, linestyle=dashed](A)(B)(C)
  \newpsstyle{IfcDot}{dotstyle=+, linecolor=red, dotscale=1.5}
  \psdot[style=CenterNode](\oenodeCenter{})
  \psdot[style=IfcDot](\oenodeIn{})
  \psdot[style=IfcDot](\oenodeOut{})
  \rput[b](\oenodeCenter{}|0,0){\opt{prismalign=auto}}
  \pnode(7,0){A}\pnode(10,1.8){B}\pnode(13,0){C}
  \psdot(A)\uput[90](A){\prm{in}}
  \psdot(B)\uput[90](B){\prm{center}}
  \psdot(C)\uput[90](C){\prm{out}}
  \optprism[prismsize=2, prismalign=center](A)(B)(C)
  \psline[style=Refline, linestyle=dashed](A)(B)(C)
  \psdot[style=CenterNode](\oenodeCenter{})
  \psdot[style=IfcDot](\oenodeIn{})
  \psdot[style=IfcDot](\oenodeOut{})
  \rput[b](\oenodeCenter{}|0,0){\opt{prismalign=center}}
\end{pspicture}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
% 
% \ifGERMAN\section{Umkehrprisma}\fi
% \ifENGLISH\section{Right-angle prism}\fi
% 
% \begin{ltxsyntax}
% \tripoledesc{rightangleprism}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
  \psdot(1.8,1)
  \rightangleprism[beam](0,1.5)(1.8,1)(0,0.5){RA}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% \ifGERMAN
% Das Umkehrprisma wird so ausgerichtet, dass der einfallende und der
% reflektierte Strahl parallel sind und der \prm{center} Knoten vertikal
% zentriert in dem Prisma liegt.
% \fi
% \ifENGLISH
% The right-angle prisms is align such that the incoming and reflected
% beam are parallel and the \prm{center} node is vertically centered in
% the prism.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3.5,2)
  \pnode(0,2){A}\pnode(2.5,0.5){G}\pnode(0,1.5){B}
  \begin{optexp}
  \rightangleprism[beam, showifcnodes, showoptdots](A)(G)(B){RA}
  \end{optexp}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \begin{optionlist}
% \numitem[1.5]{raprismsize}
% \ifGERMAN Die Länge der Eingangsfläche.\fi
% \ifENGLISH The length of the input plane.\fi
% \end{optionlist}
% 
% \ifGERMAN\section{Pentaprisma}\fi
% \ifENGLISH\section{Penta prism}\fi
% 
% \begin{ltxsyntax}
% \tripoledesc{pentaprism}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
  \pentaprism[beam](0,1)(2,1)(2,0){PP}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% 
% \begin{optionlist}
%   \numitem[0.7]{pentaprismsize} 
%   \ifGERMAN Die Länge der Eingangs- und Ausgangsfläche.\fi
%   \ifENGLISH The length of the input and output plane.\fi
% \end{optionlist}
% 
% 
% \ifGERMAN\chapter{Faserkomponenten}\fi
% \ifENGLISH\chapter{Fiber components}\fi
% \label{chap:fibercomp}
%
% \ifENGLISH This chapter describes all fiber components and their
% options. They differ from free-ray components in that they are
% connected by default with fibers to their reference nodes, and that
% they cannot be used for raytracing. Instead of automatic fiber
% connections the components can also be connected manually with fibers,
% see \prettyref{sec:drawfiber}.
%
% Most components require only two reference nodes and are handled like
% the free-ray dipoles. Some special components like couplers
% (\prettyref{sec:coupler}) and circulators
% (\prettyref{sec:optcirculator}) are treated differently.
% \fi
% \ifGERMAN In diesem Kapitel werden alle Faserkomponenten und deren
% Parameter beschrieben. Diese werden automatisch über Fasern mit ihren
% Referenzknoten verbunden und unterstützen kein Raytracing. Anstelle
% der automatischen Faserverbindungen können die Komponenten auch
% manuell mit Fasern verbunden werden, siehe \prettyref{sec:drawfiber}.
%
% Die meisten Komponenten benötigen nur zwei Referenzknoten und werden
% wie die Freistrahlzweipole behandelt. Manche spezielle Komponenten wie
% Koppler (\ref{sec:coupler}) und Zirkulatoren (\ref{cmd:optcirculator})
% werden anders ausgerichtet.
% \fi
%
% \begin{optionlist}
%   \boolitem{usefiberstyle} 
%   \ifGERMAN
%   Bei manchen Komponenten (z.B. \Lcs{optfilter} oder \Lcs{optmzm}) kann es
%   vorteilhaft sein interne Faserteile hervorzuheben. Mit diesem Parameter
%   werden z.B. die durchlässigen Teile eines Filter angezeigt und mit dem
%   \Lstyle{Fiber}-Stil gezeichnet. In der Dokumentation ist dieses Verhalten
%   angeschaltet um die betroffenen Bereiche hervorzuheben.
%   \fi
%   \ifENGLISH
%   For some components (e.g. \Lcs{optfilter} or \Lcs{optmzm}) it can be nice
%   to highlight some internals. For example, if this option is enabled the
%   passing parts of the optical filter are drawn with the \Lstyle{Fiber}
%   style. In the documentation this parameter is enabled to show the parts
%   which are affected.
%   \fi
% \end{optionlist}
%
% \ifGERMAN\section{Optische Faser}\fi
% \ifENGLISH\section{Optical fiber}\fi
% 
% \begin{ltxsyntax}
% \fiberdipoledesc{optfiber}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.5)
  \optfiber[label=0.3](0,0.5)(3,0.5){SSMF}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% \begin{optionlist}
% \intitem[3]{fiberloops} 
% \ifGERMAN Anzahl der Faserschleifen.\fi
% \ifENGLISH Number of the fiber loops.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]fiberloops}]
\begin{pspicture}(3,1.5)
  \optfiber[fiberloops=2, label=0.3](0,0.5)(3,0.5){SSMF}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \numitem[0.4]{fiberloopradius}
% \ifGERMAN Radius der Faserschleifen.\fi
% \ifENGLISH Radius of the fiber loops.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]fiberloopradius}]
\begin{pspicture}(3,1.5)
  \optfiber[fiberloopradius=0.2, label=0.3](0,0.5)(3,0.5){SSMF}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \numitem[0.3]{fiberloopsep}
% \ifGERMAN Abstand zwischen zwei aufeinanderfolgenden Faserschleifen.\fi
% \ifENGLISH Separation between two successive fiber loops.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]fiberloopsep}]
\begin{pspicture}(3,1.5)
  \optfiber[fiberloopsep=0.6, label=0.3](0,0.5)(3,0.5){SSMF}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
% 
% \ifGERMAN\section{Optischer Verstärker}\fi
% \ifENGLISH\section{Optical amplifier}\fi
%
% \begin{ltxsyntax}
% \fiberdipoledesc{optamp}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.5)
  \optamp(0,1)(3,1){EDFA}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% 
% \begin{optionlist}
% \optitem[0.8]{optampsize}{\prm{num} or \prm{width} \prm{height}}
% \ifGERMAN 
% Eine einzelne Zahl gibt die Seitenlänge des Verstärkers an, zwei Zahlen die
% Breite und Höhe. Beachten Sie, dass \opt{optampsize=1} und \opt{optampsize=1
% 1} nicht dasselbe Ergebnis liefern. Alternativ kann das Verhältnis zwischen
% Höhe und Breite mit \opt{xunit} und \opt{yunit} geändert werden.
% \fi
% \ifENGLISH
% A single number gives the side length of the amplifier, two numbers the width
% and height. Note, that \opt{optampsize=1} and \opt{optampsize=1 1} do not give
% the same result. You may also change the relation of width and height with
% \opt{xunit} and \opt{yunit}.
% \fi
% \end{optionlist}
% 
% \ifGERMAN\section{Mach-Zehnder-Modulator}\fi
% \ifENGLISH\section{Mach--Zehnder modulator}\fi
% 
% \begin{ltxsyntax}
% \fiberdipoledesc{optmzm}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.5)
  \optmzm(0,1)(3,1){MZM}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% 
% \begin{optionlist}
% \optitem[0.8]{optmzmsize}{\prm{num} or \prm{width} \prm{height}}
% \ifGERMAN 
% Eine einzelne Zahl gibt die Höhe des Modulators an, die Breite ist \opt{1.6} mal die
% Höhe. Zwei Zahlen geben Breite und Höhe des Modulators direkt an.
% \fi
% \ifENGLISH
% A single number gives the modulator height, the width is \opt{1.6} times the
% height. Two numbers define width and height directly.
% \fi
% \end{optionlist}
% 
% \ifGERMAN\section{Polarisationssteller}\fi
% \ifENGLISH\section{Polarization controller}\fi
% 
% \begin{ltxsyntax}
% \fiberdipoledesc{polcontrol}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.5)
  \polcontrol(0,1)(3,1){PC}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% 
% \begin{optionlist}
% \numitem[0.15]{polcontrolsize} 
% \ifGERMAN Der Radius der Polarisationssteller-Kreise.\fi
% \ifENGLISH The radius of the polarization controller circles.\fi
%
% \choitem[linear]{polcontroltype}{linear, triangle}
% \ifGERMAN Der Typ des Polarisationsstellers.\fi
% \ifENGLISH The type of polarization controller.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]polcontroltype}]
\begin{pspicture}(3,1.5)
  \polcontrol[polcontroltype=triangle](0,1)(3,1){PC}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
% 
% \ifGERMAN\section{Isolator}\fi
% \ifENGLISH\section{Isolator}\fi
% 
% \begin{ltxsyntax}
% \fiberdipoledesc{optisolator}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.5)
  \optisolator(0,1)(3,1){isolator}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% 
% \begin{optionlist}
% \optitem[0.6]{isolatorsize}{\prm{num} or \prm{width} \prm{height}}
% \ifGERMAN 
% Eine einzelne Zahl gibt die Höhe des Isolators an, die Breite ist \opt{1.6} mal die
% Höhe. Zwei Zahlen geben Breite und Höhe des Isolators direkt an.
% \fi
% \ifENGLISH
% A single number gives the isolator height, the width is \opt{1.6} times the
% height. Two numbers define width and height directly.
% \fi
% \end{optionlist}
%
% \begin{stylelist}
% \styleitem[linewidth=2\cs{pslinewidth}, arrowinset=0]{IsolatorArrow} 
% \ifGERMAN 
% Der Stil für den Isolatorpfeil. Das kann insbesondere nützlich sein um
% die Länge des Pfeils zu verändern. 
% \fi
% \ifENGLISH 
% The style of the isolator arrow. This can be especially useful to
% adapt the length of the arrow.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]IsolatorArrow}]
\begin{pspicture}(3,1.5)
  \addtopsstyle{IsolatorArrow}{xunit=1.2}
  \optisolator(0,1)(3,1){isolator}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{stylelist}
% 
% \ifGERMAN\section{Optischer Schalter}\fi
% \ifENGLISH\section{Optical switch}\fi
% 
% \begin{ltxsyntax}
% \fiberdipoledesc{optswitch}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.5)
  \optswitch(0,1)(3,1){opened switch}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% 
% \begin{optionlist}
% \optitem[0.8]{switchsize}{\prm{num} or \prm{width} \prm{height}}
% \ifGERMAN 
% Wird nur eine Zahl angegeben, so ist das die Seitenlänge des
% Schalters, andernfalls können Breite und Höhe getrennt angegeben
% werden.
% \fi
% \ifENGLISH 
% A single number defines the side length of the switch, otherwise the
% height and width can be specified separately.
% \fi
%
% \choitem[opened]{switchstyle}{opened, closed} 
% \ifGERMAN Der Zustand des Schalters kann geschlossen (\opt{closed}) oder
% geöffnet (\opt{opened}) sein.
% \fi
% \ifENGLISH Indicate the switch as \opt{opened} or \opt{closed}.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]switchstyle}]
\begin{pspicture}(3,1.5)
  \optswitch[switchstyle=closed](0,1)(3,1){closed switch}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
% 
% \ifGERMAN\section{Faserverzögerungstrecke}\fi
% \ifENGLISH\section{Fiber delay line}\fi
% 
% \begin{ltxsyntax}
% \fiberdipoledesc{fiberdelayline}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.5)
  \fiberdelayline(0,1)(3,1){delay line}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% 
% \begin{optionlist}
% \optitem[0.6]{fdlsize}{\prm{num} or \prm{width} \prm{height}}
% \ifGERMAN 
% Eine einzelne Zahl gibt die Höhe der Komponente an, die Breite ist \opt{1.6}
% mal die Höhe. Zwei Zahlen geben Breite und Höhe der Komponente direkt an.
% \fi
% \ifENGLISH
% A single number gives the component height, the width is \opt{1.6} times the
% height. Two numbers define width and height directly.
% \fi
% \end{optionlist}
%
% \begin{stylelist}
% \styleitem[arrowinset=0, arrows=->]{FdlArrow} 
% \ifGERMAN 
% Der Stil für den Pfeil. Das kann insbesonders nützlich sein um die
% Länge des Pfeils zu verändern, die bei geänderter Größe nicht mehr
% passend sein kann, oder um den Pfeil zu spiegeln.
% \fi
% \ifENGLISH 
% The style of the arrow. This can be especially useful to
% adapt the length of the arrow which may not be appropriate depending
% on the \opt{fdlsize}, or to mirror the arrow.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]FdlArrow}]
\begin{pspicture}(3,1.5)
  \addtopsstyle{FdlArrow}{xunit=-1}
  \fiberdelayline(0,1)(3,1){delay line}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{stylelist}
% 
% \ifGERMAN\section{Polarisator}\fi
% \ifENGLISH\section{Polarizer}\fi
% 
% \begin{ltxsyntax}
% \fiberdipoledesc{optfiberpolarizer}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.5)
  \optfiberpolarizer(0,1)(3,1){polarizer}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% 
% \begin{optionlist}
% \optitem[0.6]{fiberpolsize}{\prm{num} or \prm{width} \prm{height}}
% \ifGERMAN 
% Eine einzelne Zahl gibt die Höhe der Komponente an, die Breite ist \opt{1.6}
% mal die Höhe. Zwei Zahlen geben Breite und Höhe der Komponente direkt an.
% \fi
% \ifENGLISH
% A single number gives the component height, the width is \opt{1.6} times the
% height. Two numbers define width and height directly.
% \fi
% \end{optionlist}
% 
%
% \ifGERMAN\section{Optischer Zirkulator}\fi
% \ifENGLISH\section{Optical circulator}\fi
% \label{sec:optcirculator}
% \begin{ltxsyntax}
% \xLfmultipole{optcirculator}%
% \cmditem{optcirculator}(left)(right)(bottom){label}%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
  \addtopsstyle{Fiber}{arrows=->}
  \addtopsstyle{FiberOut1}{linecolor=blue}
  \addtopsstyle{FiberOut2}{linecolor=green!80!black}
  \optcirculator(0,1)(3,1)(1.5,0){Circulator}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% \begin{optionlist}
% \numitem[0.8]{optcircsize}
% \ifGERMAN Der Durchmesser des Zirkulators.\fi
% \ifENGLISH The diameter of the circulator.\fi
%
% \numitem[-160]{optcircangleA}
% \ifGERMAN Der Startwinkel des internen Pfeils.\fi
% \ifENGLISH The starting angle of the internal arrow.\fi
%
% \numitem[-20]{optcircangleB}
% \ifGERMAN Der Endwinkel des internen Pfeils.\fi
% \ifENGLISH The ending angle of the internal arrow.\fi
%
% \optitem{optcircangle}{\prm{num} \prm{num}}
% \ifGERMAN Kurzschreibweise um beide Winkel gleichzeitig zu setzen.\fi
% \ifENGLISH Short notation to specifying both angles.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]optcircangle}]
\begin{pspicture}(3,1.5)
  \optcirculator[optcircangle=0 -90](0,1)(3,1)(1.5,0)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
% 
% \begin{stylelist}
% \styleitem[unit=0.7, arrows=->, arrowinset=0]{OptCircArrow}
% \ifGERMAN 
% Der Stil für den internen Pfeil. Damit wird sowohl die Richtung des Pfeils als
% auch die Größe des Bogens bestimmt.
% \fi
% \ifENGLISH The style of the internal arrow. It specifies the direction of the
% arrow and the size of the arc.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{optcircangle, OptCircArrow}}]
\begin{pspicture}(3,1.5)
  \newpsstyle{OptCircArrow}{unit=0.5, arrows=<-, arrowinset=0}
  \optcirculator[optcircangle=0 -90](0,1)(3,1)(1.5,0)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{stylelist}
%
% \ifENGLISH
% The circulator is positioned by default such that the input and output fibers
% are orthogonal to each other, like shown in the example:
% \fi
% \ifGERMAN
% Der Zirkulator wird so positioniert, dass Eingangs- und Ausgangsverbindung
% senkrecht zueinander stehen, wie das folgende Beispiel verdeutlicht:
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
  \addtopsstyle{Fiber}{arrowscale=1.3, arrows=->, arrowinset=0}
  \optcirculator(0,0.5)(3,2)(1.5,0)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifENGLISH The positioning parameters (\prettyref{sec:positioning}) refer to
% the reference nodes \prm{left} and \prm{right} as usual and are not related
% to the automatic position. This implies, that the default position is not
% equivalent to \Lkeyword{position}\opt{=0.5}.
% \fi
% \ifGERMAN Die Positionierungsparameter (\prettyref{sec:positioning}) beziehen
% sich wie üblich auf die Referenzknoten \prm{left} und \prm{right}, und nicht
% auf die automatisch bestimmte Position. Das bedeutet auch, dass die
% automatische Position i.a. nicht mit \Lkeyword{position}\opt{=0.5}
% übereinstimmt.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
  \addtopsstyle{Fiber}{arrowscale=1.3, arrows=->, arrowinset=0, ncurv=1.5}
  \optcirculator[position=0.5](0,0.5)(3,2)(1.5,0)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \ifGERMAN\section{Faserkoppler}\fi
% \ifENGLISH\section{Fiber coupler}\fi
% \label{sec:coupler}
% 
% \ifGERMAN Es stehen drei Faserkoppler zur Verfügung, die alle die gleichen
% Formen und Parameter verwenden.
% \fi
% \ifENGLISH The package provides three fiber couplers which all share the same
% shapes and parameters.
% \fi
% \begin{ltxsyntax}
% \xLfmultipole{optcoupler}%
% \cmditem{optcoupler}(tl)(bl)(tr)(br){label}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(0,-0.4)(3,1)
  \optcoupler(0,1)(0,0)(3,1)(3,0){optcoupler}  
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \xLfmultipole{wdmcoupler}%
% \cmditem{wdmcoupler}(tl)(bl)(r){label}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(0,-0.4)(3,1)
  \wdmcoupler(0,1)(0,0)(3,0.5){wdmcoupler}  
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \xLfmultipole{wdmsplitter}%
% \cmditem{wdmsplitter}(l)(tr)(br){label}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(0,-0.4)(3,1)
  \wdmsplitter(0,0.5)(3,1)(3,0){wdmsplitter}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% \begin{optionlist}
% \optitem[0.2]{couplersize}{\prm{num} or \prm{width} \prm{height}}
% \ifGERMAN 
% Wird eine Zahl angegeben, so ist die Breite des Kopplers doppelt so groß, die
% Höhe entspricht \opt{0.8} mal dem Wert. Mit zwei Zahlen werden Breite und Höhe
% direkt angegeben.
% \fi
% \ifENGLISH
% For a single number the width is twice this value, the height \opt{0.8} times
% this value. Two numbers define width and height directly.
% \fi
%
% \numitem[0.1]{couplersep} 
% \ifGERMAN Der vertikale Abstand zwischen zwei Faserports.\fi
% \ifENGLISH The vertical distance between two fiber ports.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{couplersep}}]
\begin{pspicture}(0,-0.5)(3,1)
  \optcoupler[couplersep=0](0,1)(0,0)(3,1)(3,0){coupler}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \choitem[ellipse]{couplertype}{none, ellipse, rectangle, cross}
% \ifGERMAN Wählt zwischen unterschiedlichen Kopplertypen.\fi
% \ifENGLISH Select between different coupler types.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{couplertype}}]
\begin{pspicture}(3,4.5)
  \psset{labeloffset=0.5}
  \optcoupler[couplertype=none]%
       (0,4.5)(0,3.5)(3,4.5)(3,3.5){none}
  \optcoupler[couplertype=rectangle]%
       (0,3)(0,2)(3,3)(3,2){rectangle}
  \optcoupler[couplertype=cross]%
       (0,1.5)(0,0.5)(3,1.5)(3,0.5){cross}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \choitem[center]{coupleralign}{t, top, b, bottom, c, center}
% \ifGERMAN Die Ausrichtung des Kopplers bezüglich der
% Referenzknoten. Beachten Sie, dass die Position der Komponentenmitte
% und damit der Beschriftung von dieser Einstellung abhängt (siehe
% \ref{sec:centernode}).
% \fi
% \ifENGLISH The alignment of the coupler with respect to the reference
% nodes. Note, that the exact position of the coupler center and
% accordingly that of the label depends on this setting (see
% \ref{sec:centernode}).
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{coupleralign}}]
\begin{pspicture}(3,3)
  \psset{labeloffset=0.4}
  \optcoupler[coupleralign=top]%
               (0,3)(0,2)(3,3)(3,2){top}
  \optcoupler[coupleralign=bottom]%
               (0,1.5)(0,0.5)(3,1.5)(3,0.5){bottom}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \choitem[center]{align}{top, bottom, center}
% \ifGERMAN Dieser Parameter wurde in Version 3.0 in \Lkeyword{coupleralign}
% umbenannt und ist seitdem veraltet.
% \fi
% \ifENGLISH This parameter was renamed in version 3.0 to
% \Lkeyword{coupleralign} and is deprecated.
% \fi
%
% \boolitem*[true]{variable}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{variable}}]
\begin{pspicture}(3,1)
  \optcoupler[variable](0,1)(0,0)(3,1)(3,0)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
%
% \begin{stylelist}
% \styleitem[arrowinset=0, arrows=->]{VariableCoupler}
% \ifGERMAN
%   Der Stil des Pfeiles des verstellbaren Kopplers.
% \fi
% \ifENGLISH
% The style of the arrow of the variable coupler.
% \fi
% \end{stylelist}
%
% \ifGERMAN
% Jeder Koppler hat eine Variante, die nur zwei Knoten benötigt, einen Eingangs-
% und einen Ausgangsknoten. \Lcs{optcoupler} verwendet jeden dieser Knoten
% zweimal, \Lcs{wdmsplitter} verwendet den Knoten \prm{out} zweimal und
% \Lcs{wdmcoupler} verwendet \prm{in} zweimal. Das kann sehr praktisch sein,
% wenn man für einen Koppler die automatischen Verbindungen nicht verwendet,
% sondern die Komponente manuell verbindet.
% \fi
% \ifENGLISH 
% Every coupler has a variant which needs only two nodes, one input and one
% output node. For \Lcs{optcoupler}, both nodes are used twice,
% \Lcs{wdmsplitter} uses node \prm{out} twice, and \Lcs{wdmcoupler} uses node
% \prm{in} twice. This can be very useful if you do not use the automatic
% connections but connect the components manually.
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(4,2)
  \pnode(0,1){A}\pnode(4,1){B}
  \psset[optexp]{fiber=none}
  \wdmsplitter[position=0.2, coupleralign=b](A)(B)
  \wdmcoupler[position=0.8, coupleralign=t](A)(B)
  \drawfiber{(A)}{1}{2}{(B)}
  \drawfiber{1}{([offset=0.5, Xnodesep=1]\oenodeIfc{2}{1})}
  \drawfiber{([offset=-0.5, Xnodesep=-1]\oenodeIfc{2}{2})}{2}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \ifGERMAN\subsection{Eingangs- und Ausgangsknoten}\fi
% \ifENGLISH\subsection{Input and output nodes}\fi
% \label{sec:coupler-nodes}
%
% \ifGERMAN
% Die Definition der Eingangs- und Ausgangsknoten aus \prettyref{sec:ifcnode}
% ist für Koppler nicht anwendbar. Hier werden die Knoten einfach von \opt{1}
% (links oben) bis \opt{N} (rechts unten) durchnummeriert.
% \fi
% \ifENGLISH
% The definition of input and output nodes from \prettyref{sec:ifcnode} cannot
% be applied to couplers. Here, the nodes are simply numbered from \opt{1} (left
% top) to \opt{N} (right bottom).
% \fi
% \begin{center}
% \begin{pspicture}(11,2)
% \psset{couplersize=0.5, couplertype=rectangle, couplersep=0.2}
% \wdmsplitter(0, 1.25)(3,2)(3,0.5)
% \psdot(\oenodeIfc{1}{})\uput[120](\oenodeIfc{1}{}){1}
% \psdot(\oenodeIfc{2}{})\uput[90](\oenodeIfc{2}{}){2}
% \psdot(\oenodeIfc{N}{})\uput[-90](\oenodeIfc{N}{}){N}
% \wdmcoupler(4, 2)(4,0.5)(7,1.25)
% \psdot(\oenodeIfc{1}{})\uput[90](\oenodeIfc{1}{}){1}
% \psdot(\oenodeIfc{2}{})\uput[-90](\oenodeIfc{2}{}){2}
% \psdot(\oenodeIfc{N}{})\uput[60](\oenodeIfc{N}{}){N}
% \optcoupler(8,2)(8,0.5)(11,2)(11,0.5)
% \psdot(\oenodeIfc{1}{})\uput[90](\oenodeIfc{1}{}){1}
% \psdot(\oenodeIfc{2}{})\uput[-90](\oenodeIfc{2}{}){2}
% \psdot(\oenodeIfc{3}{})\uput[90](\oenodeIfc{3}{}){3}
% \psdot(\oenodeIfc{N}{})\uput[-90](\oenodeIfc{N}{}){N}
% \rput[b](1.5,0){\nxLcs{wdmsplitter}}
% \rput[b](5.5,0){\nxLcs{wdmcoupler}}
% \rput[b](9.5,0){\nxLcs{optcoupler}}
% \end{pspicture}
% \end{center}
%
%
% \ifGERMAN\subsection{Referenzknoten}\fi
% \ifENGLISH\subsection{Reference nodes}\fi
% \label{sec:coupler-refnodes}
%
% \ifGERMAN
% Die Definition der Referenzknoten aus \prettyref{sec:refnode} ist für Koppler
% nicht anwendbar und hängt von \Lkeyword{coupleralign} ab.
% \fi
% \ifENGLISH
% The definition of reference nodes from \prettyref{sec:refnode} cannot be
% applied to couplers and depends on \Lkeyword{coupleralign}.
% \fi
% \begin{center}
% \begin{pspicture}(12,2)
% \psset{couplersize=0.5, couplertype=rectangle, couplersep=0.2}
% \optcoupler(0, 2)(0,0.7)(3,2)(3,0.7)
% \psdot(\oenodeRefA{})\uput[90](\oenodeRefA{}){RefA}
% \psdot(\oenodeRefB{})\uput[90](\oenodeRefB{}){RefB}
% \optcoupler[coupleralign=top](4.5, 2)(4.5,0.7)(7.5,2)(7.5,0.7)
% \psdot(\oenodeRefA{})\uput[-90](\oenodeRefA{}){RefA}
% \psdot(\oenodeRefB{})\uput[-90](\oenodeRefB{}){RefB}
% \optcoupler[coupleralign=bottom](9, 2)(9,0.7)(12,2)(12,0.7)
% \psdot(\oenodeRefA{})\uput[90](\oenodeRefA{}){RefA}
% \psdot(\oenodeRefB{})\uput[90](\oenodeRefB{}){RefB}
% \rput[b](1.5,0){\opt{coupleralign=none}}
% \rput[b](6,0){\opt{coupleralign=top}}
% \rput[b](10.5,0){\opt{coupleralign=bottom}}
% \end{pspicture}
% \end{center}
%
%
% \ifGERMAN\section{Faserbox}\fi
% \ifENGLISH\section{Fiber box}\fi
%
% \begin{ltxsyntax}
% \xLfmultipole{fiberbox}%
% \cmditem{fiberbox}(in)(out){label}
% \cmditem*{fiberbox}(tl)(bl)(tr)(br){label}
% \end{ltxsyntax}
% 
% \ifGERMAN 
% Eine \Lcs{fiberbox} kann entweder mit zwei, oder mit vier Knoten
% positioniert werden. Die Wahl beeinflusst die Position der Komponente
% und der Komponentenknoten und die automatischen Faserverbindungen.
%
% Werden nur zwei Knoten verwendet, dann sind das die Referenzknoten und
% der Abstand zwischen zwei benachbarten Eingangs- oder Ausgangsknoten
% muss manuell angegeben werden (siehe \Lkeyword{fiberboxsepin} und
% \Lkeyword{fiberboxsepout}). Nur die Seiten der Komponente wird
% automatische mit Fasern verbunden, die nur einen einzigen Knoten hat
% (siehe \Lkeyword{fiberboxcount} und das folgende Beispiel).
% \fi
% \ifENGLISH 
% A \Lcs{fiberbox} can be positioned either with two, or four nodes which
% affects the positioning of the component and the interface nodes, and the
% automatic fiber connections.
% 
% If only two nodes are used these are the reference nodes and the separation
% between the components input and output nodes must be specified manually (see
% \Lkeyword{fiberboxsepin} and \Lkeyword{fiberboxsepout}). Only the side of the
% component is connected automatically which has a single node only (see
% \Lkeyword{fiberboxcount} and the following example).
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-2,5-5}]
\begin{pspicture}(3,2)
  \fiberbox[fiberboxcount=1x2, showifcnodes](0,1)(3,1)
  \psdot(\oenodeRefA{})\uput[90](\oenodeRefA{}){RefA}
  \psdot(\oenodeRefB{})\uput[90](\oenodeRefB{}){RefB}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN 
% Werden vier Knoten verwendet, dann wird die Lage der Komponentenknoten
% und deren Abstand automatisch bestimmt. Die Komponente wird zwischen
% der Mitte der beiden Eingangsknoten und der Mitte der beiden
% Ausgangsknoten positioniert. Der erste Eingangsknoten wird an dem
% \prm{tl}-Knoten ausgerichtet, der letzte Eingangsknoten an dem
% \prm{bl}-Knoten. Die übrigen Eingangsknoten werden dazwischen
% gleichverteilt. Die Ausgangsknoten werden entsprechend behandelt. Die
% vier angegebenen Knoten werden automatisch mit den jeweils
% zugeordneten Komponentenknoten verbunden.
% \fi
% \ifENGLISH
% When four nodes are used the interface nodes and their separation are
% determined automatically. The component is positioned between the
% center of the two input and the center of the two output nodes. The
% first input interface node is aligned with the \prm{tl} node, the last
% input node is aligned with \prm{bl}, all other input nodes are equally
% distributed between these. The output nodes are handled
% accordingly. The four specified nodes are connected automatically to
% the component, each with the interface node it is aligned to.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-2,5-5}]
\begin{pspicture}(3,2)
  \fiberbox[fiberboxcount=3x4, showifcnodes](0.5,1.6)(0,0.4)(2.5,2)(3,0)
  \psdot(\oenodeRefA{})\uput[90](\oenodeRefA{}){RefA}
  \psdot(\oenodeRefB{})\uput[90](\oenodeRefB{}){RefB}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \begin{optionlist}
%   \numitem[1]{fiberboxwidth}
%   \ifGERMAN Die Breite der Faserbox.\fi
%   \ifENGLISH The width of the fiber box.\fi
%
%   \numitem[0]{fiberboxheight}
%   \ifGERMAN Die Höhe der Faserbox. Ist die Höhe kleiner als der Platz
%   der von den Eingangs- oder Ausgangsknoten benötigt wird, dann wird
%   die Höhe automatisch berechnet. Die berechnete Höhe ist
%   $\text{max}\,(\text{sepin}\times(\text{N}-1),
%   \text{sepout}\times(\text{M}-1))$.
%   \fi
%   \ifENGLISH The height of the fiber box. If the height is lower than
%   the space required by the input or output nodes, it is calculated
%   automatically. The calculated height is 
%   $\text{max}\,(\text{sepin}\times(\text{N}-1),
%   \text{sepout}\times(\text{M}-1))$. 
%   \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2.8)
  \psset[optexp]{innerlabel, fiberboxwidth=1, fiberboxcount=1x2}
  \fiberbox(0,2)(0,2)(3,2.5)(3,1.5){auto}
  \fiberbox[fiberboxheight=1.05](0,0.5)(0,0.5)(3,1)(3,0){fix}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
%   \optitem{fiberboxsize}{\prm{width} \prm{height}}
%   \ifGERMAN Die Breite und Höhe der Faserbox, ist äquivalent zum Aufruf von
%   \Lkeyword{fiberboxwidth} und \Lkeyword{fiberboxheight}.
%   \fi
%   \ifENGLISH The width and height of the fiber box, is equivalent to calling
%   both \Lkeyword{fiberboxwidth} and \Lkeyword{fiberboxheight}.
%   \fi
%
%   \numitem[0.2]{fiberboxsepin}
%   \ifGERMAN Der Abstand zwischen zwei Eingangsknoten. Dieser Wert wird nur
%   verwendet, falls die Faserbox mit zwei Knoten positioniert wird. Ansonsten
%   wird der Abstand automatisch ermittelt wird.
%   \fi
%   \ifENGLISH The separation between two input nodes. This value is
%   used only if the fiber box is positioned with two nodes. Otherwise
%   the separation is calculated automatically.
%   \fi
%
%   \numitem[0.2]{fiberboxsepout}
%   \ifGERMAN Analog zu \Lkeyword{fiberboxsepin}, aber für die Ausgangsknoten.\fi
%   \ifENGLISH Equivalent to \Lkeyword{fiberboxsepout}, but for the output nodes.\fi
%
%   \optitem[2x2]{fiberboxcount}{\prm{N}x\prm{M}}
%   \ifGERMAN Anzahl der Eingangs- (\prm{N}) und Ausgangsknoten (\prm{M}).\fi
%   \ifENGLISH Number of input (\prm{N}) and output nodes (\prm{M}).\fi
% \end{optionlist}
%
% \ifGERMAN Für bestimmte Parameterkombinationen ist eine \Lcs{fiberbox}
% äquivalent zu einer \Lcs{optbox}.
% \fi
% \ifENGLISH For certain parameter configurations a \Lcs{fiberbox} is
% equivalent to an \Lcs{optbox}.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(0,0.3)(3,2.6)
  \psset[optexp]{label=0.6}
  \fiberbox[fiberboxsize=1.2 0.6, fiberboxcount=1x1](0,2.5)(3,2.5){fiberbox}
  \optbox[optboxsize=1.2 0.6, fiber](0,1)(3,1){optbox}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \psset{usefiberstyle=false}
%
% \ifGERMAN\chapter{Hybridkomponenten}\fi
% \ifENGLISH\chapter{Hybrid components}\fi
% \label{sec:hybridcomp}
%
% \ifENGLISH This chapter describes the components which can be used both for
% free-ray and fiber optics but which differ from these two categories.
%
% The optical filter (\Lcs{optfilter}) is connected by default with automatic
% fiber connections, but can likewise be used with free-ray beams, in contrast
% to the fiber components (\prettyref{chap:fibercomp}). The fiber collimator
% (\Lcs{fibercollimator}) has one interface only, the other connection is a
% fiber.
% \fi
% \ifGERMAN Dieses Kapitel beschreibt die Komponenten, die sowohl für
% Freistrahl- als auch Faseroptik zu verwenden sind, sich von diesen aber etwas
% abgrenzen.
%
% Der optische Filter (\Lcs{optfilter}) wird mit den Voreinstellungen aber als
% Faserkomponente gehandhabt, kann jedoch im Gegensatz zu den reinen
% Faserkomponenten (\prettyref{chap:fibercomp}) auch als Freistrahlkomponente
% verwendet werden. Der Faserkollimator (\Lcs{fibercollimator}) hat nur eine
% Faser, die andere Verbindung ist Freistrahl.
% \fi
%
% \ifGERMAN\section{Optischer Filter}\fi
% \ifENGLISH\section{Optical filter}\fi
% \psset{usefiberstyle}
% \begin{ltxsyntax}
% \fiberdipoledesc{optfilter}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.5)
  \optfilter(0,1)(3,1){bandpass}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% 
% \begin{optionlist}
% \numitem[0.8]{filtersize}
% \ifGERMAN Die Größe des Filters.\fi
% \ifENGLISH The size of the filter.\fi
%
% \choitem[bandpass]{filtertype}{bandpass, bandstop, lowpass, highpass}
% \ifGERMAN Wähle zwischen unterschiedlichen Filtertypen.\fi
% \ifENGLISH Select between different filter types.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{filtertype}}]
\begin{pspicture}(3,1.5)
  \optfilter[filtertype=bandstop](0,1)(3,1){bandstop}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{filtertype}}]
\begin{pspicture}(3,1.5)
  \optfilter[filtertype=lowpass](0,1)(3,1){lowpass}
\end{pspicture}
\end{LTXexample}

\begin{LTXexample}[morekeywords={[21]{filtertype}}]
\begin{pspicture}(3,1.5)
  \optfilter[filtertype=highpass](0,1)(3,1){highpass}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \numitem[0]{filterangle}
% \ifGERMAN Dreht das «Innere» des Filters relativ zum seinem
% Rahmen. Anstattdessen kann auch \Lkeyword{innercompalign} verwendet
% werden.
% \fi
% \ifENGLISH Rotates the «inner» part of the filter relativ to its
% frame. Alternatively \Lkeyword{innercompalign} can be used.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{filterangle}}]
\begin{pspicture}(2,2)
  \optfilter(0.5,0)(0.5,2)
  \optfilter[filterangle=90](1.5,0)(1.5,2)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
%
% \begin{stylelist}
% \styleitem{FilterStyle}
% \ifGERMAN Beinflusst das Aussehen der internen Filterlinien.\fi
% \ifENGLISH Change the style of the internal filter lines.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]FilterStyle}]
\begin{pspicture}(3,1.5)
  \newpsstyle{OptComp}{linewidth=2\pslinewidth}
  \optfilter(0,1)(1.5,1)
  \newpsstyle{FilterStyle}{linewidth=0.5\pslinewidth}
  \optfilter(1.5,1)(3,1)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{stylelist}
%
% \ifGERMAN Verwendung als Freistrahlkomponenten, \Lkeyword{allowbeaminside} ist
% auf \opt{false} voreingestellt:
% \fi
% \ifENGLISH Usage as free-ray component, \Lkeyword{allowbeaminside} is set to
% \opt{false} by default:
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.5)
  \optfilter[fiber=none](0,1)(3,1)
  \addtopsstyle{Beam}{beamwidth=0.3,
      fillstyle=solid, fillcolor=green, opacity=0.2}
  \drawwidebeam(0,1){}(3,1)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
%
% \ifGERMAN\section{Faserkollimator}\fi
% \ifENGLISH\section{Fiber collimator}\fi
% 
% \begin{ltxsyntax}
% \xLdipole{fibercollimator}\cmditem{fibercollimator}(in)(A)(B)(out){label}%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.5)
  \fibercollimator[beam](0,1)(3,1){FC}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
%
% \ifGERMAN
% Der Faserkollimator kann mit zwei, drei oder vier Punkten verwendet
% werden. Bei zwei Punkten wird der Kollimator wie jeder andere Zweipol zwischen
% \prm{in} und \prm{out} Knoten platziert. Bei drei Punkten wird eine
% \Lcs*{psbezier} Kurve gezeichnet, wobei der mittlere Punkt doppelt verwendet
% wird. Die Positionierungsparameter (siehe \prettyref{sec:positioning}) können
% verwendet werden um den Kollimator zwischen dem \prm{in} und \prm{A} Knoten
% auszurichten.
% \fi
% \ifENGLISH
% The fiber collimator can be used with two, three or four points. With two
% points, the collimator is placed like any other dipole component between
% \prm{in} and \prm{out} node. For three nodes, the fiber is drawn as
% \Lcs*{psbezier} curve for which the central node \prm{A} is used
% twice. Positioning parameters (see \prettyref{sec:positioning}) can be used to
% shift the object between \prm{in} and \prm{A} nodes.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
   \fibercollimator[beam](0,1)(2,1)(3,2){FC}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \medskip
%
% \ifGERMAN
% Bei vier Knoten wird eine \Lcs*{psbezier} Kurve mit allen vier Knoten
% gezeichnet. Die Positionierungsparameter (siehe \prettyref{sec:positioning})
% können verwendet werden um den Kollimator zwischen den ersten beiden Knoten
% (\prm{in} und \prm{A}) zu verschieben.
% \fi
% \ifENGLISH
% For four nodes, the fiber is drawn as \Lcs*{psbezier} curve with the specified
% nodes. Positioning parameters (siehe \prettyref{sec:positioning}) can be used
% to shift the object between the first two nodes (\prm{in} and \prm{A}).
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
   \fibercollimator[beam](0,1)(2,1)(3,1)(3,2){FC}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \begin{optionlist}
% \optitem[0.3]{fibercolsize}{\prm{num} or \prm{width} \prm{height}}
% \ifGERMAN 
% Eine einzelne Zahl gibt die Seitenlänge des Kollimators an, zwei Zahlen die Breite und
% Höhe. Beachten Sie, dass \opt{fibercolsize=1} und \opt{fibercolsize=1 1} nicht
% dasselbe Ergebnis liefern. Alternativ kann das Verhältnis zwischen Höhe und
% Breite mit \opt{xunit} und \opt{yunit} geändert werden.
% \fi
% \ifENGLISH
% A single number gives the side length of the collimator, two numbers the width
% and height. Note, that \opt{fibercolsize=1} and \opt{fibercolsize=1 1} do not give
% the same result. You may also change the relation of width and height with
% \opt{xunit} and \opt{yunit}.
% \fi
% \end{optionlist}
%
% \ifGERMAN\chapter{Spezielle Knoten}\fi
% \ifENGLISH\chapter{Special nodes}\fi
% \label{sec:objnodes}
% 
% \ifGERMAN
% Jedes \nxLPack{pst-optexp}-Objekt stellt mehrere spezielle Knoten zur
% Verfügung, die mit dessen Geometrie und Positionierung zusammenhängen. Diese
% Knoten stehen für weitere Verwendung zur Verfügung.
%
% Sie sollten immer die dafür vorgesehenen Makros verwenden um auf die
% Knotennamen zuzugreifen.
% \fi
% \ifENGLISH
% Every \nxLPack{pst-optexp} object of an experimental setup provides
% several special nodes which are related to its geometry and
% positioning. They can be accessed and used for related positioning and
% drawing.
%
% You should always use the dedicated macros to access these node names.
% \fi
% \begin{ltxsyntax}
%   \cmditem{oenode}{node}{comp} 
%
% \ifGERMAN
% Das ist das grundlegende Makro mit dem auf die Knotennamen einer Komponente
% zugegriffen werden kann. Das erste Argument \prm{node} ist der Bezeichner des
% angeforderten Knotens. Das zweite Argument \prm{comp} ist der Name der
% Komponente (gemäß \prettyref{sec:namingobj}). Ist dieses leer so wird das
% zuletzt definierte Objekt verwendet.
%
% Für viele der Knoten wird ein eigenes Makro bereitgestellt, das Sie dann auch
% verwenden sollten, da sich die Namenskonventionen ändern könnten. Die Makros
% stellen sicher, dass Sie immer die passenden Knotennamen erhalten. Daher sind
% die verfügbaren Bezeichner auch nicht aufgelistet.
% \fi
% \ifENGLISH
% This is the basic command to access any node associated with a certain
% component. The first argument \prm{node} is the identifier of the requested
% node. The second argument \prm{comp} is the name of the target component
% (according to \prettyref{sec:namingobj}). If left empty, it uses the last
% component defined.
%
% For most special nodes an appropriate macro is provided, which you are
% strongly advised to use, because the naming conventions may change. Using the
% macros makes sure, that you always get the correct node names. Therefore, the
% available identifiers are not listed explicitely.
% \fi
% \end{ltxsyntax}
%
% \begin{optionlist}
%   \optitem[new]{namingscheme}{old, new} 
%   \ifGERMAN
%   Diese Option ist nur aus Kompatibilitätsgründen vorhanden. In Version 2.1
%   mussten spezielle Komponentenknoten über ihren expliziten Namen angesprochen
%   werden. Sie sollten diese Option nur dann verwenden und auf \opt{old}
%   setzen, wenn Sie in älteren Dokumenten direkt auf die Knoten zugegriffen
%   haben. Seit Version 3.0 werden Makros für den Zugriff auf die
%   Komponentenknoten bereitgestellt, so dass das eigentliche Namensschema
%   unerheblich ist.
%   \fi
%   \ifENGLISH
%   This option is for backward compatibility only. In version 2.1 special
%   component nodes had to be accessed by their explicit name. You should use
%   this option only if you accessed internal nodes directly in old
%   documents. Since version 3.0 explicit macros are provided to access all
%   special component nodes, so that the actual naming scheme does not matter.
%   \fi
%
%   \boolitem[false]{showoptdots}
%   \ifGERMAN 
%   Markiert einige der speziellen Komponentenknoten: die schwarzen Punkte sind
%   die normalen und die schwarzen Kreuze die transformierten Referenzknoten
%   (\prettyref{sec:refnode}), der rote Punkt ist der Mittelpunktknoten
%   (\prettyref{sec:centernode}) und das rote Kreuz der Beschriftungsknoten
%   (\prettyref{sec:labelnode}).
%   \fi
%   \ifENGLISH 
%   Draw some special component nodes for debugging: The black points are the
%   normal and the black crosses are the transformed reference nodes
%   (\prettyref{sec:refnode}), the red point is the center node
%   (\prettyref{sec:centernode}), and the red cross is the label node
%   (\prettyref{sec:labelnode}).
%   \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
\mirror[showoptdots, angle=10, beam](0,1)(1.9,1)(1.9,0)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
%
% \ifGERMAN\section{Komponenten-Bezeichner}\fi
% \ifENGLISH\section{Component identifiers}\fi
% \label{sec:namingobj}
%
% \ifGERMAN
% Alle Komponenten einer Aufbauskizze werden in Reihenfolge ihrer Definition im
% Code aufsteigend nummeriert, angefangen bei \opt{1}. Die Komponenten und deren
% Spezialknoten können immer über diese Nummer (ID) referenziert werden.
% \fi
% \ifENGLISH
% All components of a setup drawing are numbered automatically in increasing
% order according to their definition in the code, starting with \opt{1}. The
% components as well as their special nodes can always be accessed by this
% number (ID).
% \fi
%
% \begin{optionlist}
%   \valitem{compname}{string} 
%   \ifGERMAN
%   Weist einer Komponente einen Bezeichner zu. Die Komponente kann nun sowohl
%   über diesen Bezeichner als auch über die ID referenziert werden. Dieser
%   Parameter kann nur im optionalen Argument einer \nxLPack{pst-optexp}
%   Komponente verwendet werden. Der Bezeichner sollte innerhalb einer
%   \Lenv*{pspicture}-Umgebung eindeutig sein.
%   \fi
%   \ifENGLISH
%   Assigns a name identifier to a component, which can then be referenced both
%   by this name and by its ID. The parameter can be assigned only in the
%   optional Argument of a \nxLPack{pst-optexp} component and should be unique
%   within one \Lenv*{pspicture} environment.
%   \fi
% \iffalse
%<*ignore>
% \fi
\ifGERMAN
\begin{LTXexample}
\begin{pspicture}(2,2)
  \optbox[compname=MyBox](0,1)(2,2)
  \psdot[linecolor=red](\oenodeIn{MyBox}) % Verwende den Namen
  \psdot[linecolor=blue](\oenodeOut{1})   % Verwende die ID
  \psdot[linecolor=green](\oenodeCenter{})% Nimm die letzte Komponente
\end{pspicture}
\end{LTXexample}
\fi\ifENGLISH
\begin{LTXexample}
\begin{pspicture}(2,2)
  \optbox[compname=MyBox](0,1)(2,2)
  \psdot[linecolor=red](\oenodeIn{MyBox})% use the compname
  \psdot[linecolor=blue](\oenodeOut{1})  % use the ID
  \psdot[linecolor=green](\oenodeCenter{})  % the last component
\end{pspicture}
\end{LTXexample}
\fi
% \end{optionlist}
% \iffalse
%</ignore>
% \fi
% 
% \ifGERMAN\section{Referenzknoten}\fi
% \ifENGLISH\section{Reference nodes}\fi
% \label{sec:refnode}
%
% \begin{ltxsyntax}
%   \cmditem{oenodeRefA}{comp}
%   \cmditem{oenodeRefB}{comp}
%
%  \ifGERMAN
%  Die Eingangs- und Ausgangs-Referenzknoten.
%
%  Das sind die ursprünglichen Knoten, die für die Positionierung der Komponente
%  benutzt wurden, \nxLcs{oenodeRefA} ist der erste und \nxLcs{oenodeRefB} der
%  letzte Knoten. Diese Zuordnung ist nicht gültig für Faserkoppler
%  (\ref{sec:coupler-refnodes}) und Zirkulatoren (\ref{cmd:optcirculator}).
%  \fi
%  \ifENGLISH
%  The input and output reference nodes.
%
%  These are the original nodes which were used for the component positioning,
%  \nxLcs{oenodeRefA} is the first and \nxLcs{oenodeRefB} the last node. This
%  definition is not valid couplers (\ref{sec:coupler-refnodes}) and circulators
%  (\ref{cmd:optcirculator}).
%  \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[pos=t, linerange={1-3, 4-7}]
\begin{pspicture}(5,1)
  \pnode(0.5,0.5){A}\pnode(4.5,0.5){B}
  \optbox(A)(B)
  \psline[style=Refline](\oenodeRefA{})(\oenodeRefB{})
  \psdot(\oenodeRefA{})\uput[-90](\oenodeRefA{}){RefA}
  \psdot(\oenodeRefB{})\uput[-90](\oenodeRefB{}){RefB}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
%   \cmditem{oenodeTrefA}{comp}
%   \cmditem{oenodeTrefB}{comp}
%
%   \ifGERMAN
%   Die transformierten Eingangs- und Ausgangs-Referenzknoten.
%
%   Das sind die Referenzknoten nachdem sie zusammen mit der Komponente gemäß
%   der \Lkeyword{compshift} und \Lkeyword{angle} Parameter transformiert wurden.
%   \fi
%   \ifENGLISH
%   The transformed input and output reference nodes.
%
%   These are the input and output reference nodes which are transformed
%   together with the component according to the \Lkeyword{compshift} and
%   \Lkeyword{angle} parameters.
%   \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[pos=t, linerange={1-3,5-9}]
\begin{pspicture}(5,1.8)
  \pnode(0.5,0.5){A}\pnode(4.5,0.5){B}
  \optbox[compshift=0.5, angle=10](A)(B)
  \psline[style=Refline](\oenodeTrefA{})(\oenodeTrefB{})
  \psdot(\oenodeRefA{})\uput[-90](\oenodeRefA{}){RefA}
  \psdot(\oenodeRefB{})\uput[-90](\oenodeRefB{}){RefB}
  \psdot(\oenodeTrefA{})\uput[90](\oenodeTrefA{}){TrefA}
  \psdot(\oenodeTrefB{})\uput[90](\oenodeTrefB{}){TrefB}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
%
% \ifGERMAN\section{Mittelpunktknoten}\fi
% \ifENGLISH\section{Center node}\fi
% \label{sec:centernode}
%
% \begin{ltxsyntax}
%   \cmditem{oenodeCenter}{comp}
% 
% \ifGERMAN
% Dieser Knoten liegt, bis auf wenige Ausnahmen, wie
% z.B. \Lcs{optdetector} und \Lcs{optcoupler} (siehe unten), im
% Mittelpunkt der Komponente.
% \fi
% \ifENGLISH
% This node lays, except for a few components like
% e.g. \Lcs{optcirculator} and \Lcs{optcoupler} (see below), in the
% center of the component.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-2, 5-5, 8-8}]
\begin{pspicture}(3,2)
  \optbox(0,0.5)(3,0.5)
  \psline[style=Refline](\oenodeRefA{})(\oenodeRefB{})
  \psdot(\oenodeCenter{})
  \optdetector(0,1.5)(2.5,1.5)
  \psline[style=Refline](\oenodeRefA{})(\oenodeRefB{})
  \psdot(\oenodeCenter{})
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN Bei \Lcs{optcoupler} hängt die Position der Komponentenmitte
% von den \Lkeyword{coupleralign} Einstellungen ab.
% \fi
% \ifENGLISH For \Lcs{optcoupler} the position of the component center
% depends on the \Lkeyword{coupleralign} settings.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(0,0.3)(3,3)
  \psset[optexp]{couplersize=0.6 0.4, couplersep=0.2, couplertype=rectangle}
  \optcoupler(0,3)(0,2)(3,3)(3,2)
  \psdot(\oenodeCenter{})
  \optcoupler[coupleralign=b](0,1.5)(0,0.5)(3,1.5)(3,0.5)
  \psdot(\oenodeCenter{})
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% 
% \ifGERMAN\section{Beschriftungsknoten}\fi
% \ifENGLISH\section{Label node}\fi
% \label{sec:labelnode}
%
% \begin{ltxsyntax}
%   \cmditem{oenodeLabel}{comp}
%
%   \ifGERMAN
%   Auf diesen Knoten wird die Beschriftung platziert. Der Knoten ist auch
%   verfügbar wenn keine Beschriftung angegeben wurde. Für
%   \Lkeyword{labeloffset}\opt{=0} ist dieser Knoten
%   identisch mit dem Mittelpunktsknoten (\prettyref{sec:centernode}).
%   \fi
%   \ifENGLISH
%   The component label is placed at this node. It is also available
%   if no label was specified. The label node is identical with the center
%   node for \Lkeyword{labeloffset}\opt{=0}.
%   \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-2,5-5}]
\begin{pspicture}(3,1.5)
  \optbox(0,1)(3,1)
  \psline[style=Refline](\oenodeTrefA{})(\oenodeTrefB{})
  \psdot(\oenodeLabel{})
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
%
% \ifGERMAN\section{Externe Knoten}\fi
% \ifENGLISH\section{External nodes}\fi
% \label{sec:extnode}
%
% \begin{ltxsyntax}
%   \cmditem{oenodeExt}{comp}
%
% \ifGERMAN
% Ein externer Knoten kann an unterschiedliche Positionen entlang des
% Komponentenrandes gesetzt werden. Dieser wird nur für den externen Zugriff
% definiert, und beeinflusst in keiner Weise die Komponente.
% \fi
% \ifENGLISH
% An external node can be placed at different positions along the component
% boundary. It gets defined only for external usage and does not affect the
% component in any way.
% \fi
% \end{ltxsyntax}
% \begin{optionlist}
% \valitem{extnode}{refpoint}
% \ifGERMAN
% Bestimmt die Position des externen Knotens. \refpointexplanation Nicht
% jede Komponente unterstützt alle möglichen Kombinationen, die möglichen
% Positionen jeder Komponente sind in \prettyref{sec:overview-extnode}
% zusammengefasst.
% \fi
% \ifENGLISH
% Set the position of the external node. \refpointexplanation Not all
% components support any possible combination. The allowed positions of each
% component are listed in \prettyref{sec:overview-extnode}.
% \fi
%
% \begin{pspicture}(6,2.5) 
%   \addtopsstyle{Beam}{beaminside=false, arrows=->, arrowinset=0, arrowscale=1.5}
%    \psset{optboxsize=2.5 1.5}\ttfamily
%    \pnode(0,1.25){A}\pnode(6,1.25){B}
%    \optbox[beam, extnode=tl](A)(B)
%    \psdot(\oenodeExt{})\uput[135](\oenodeExt{}){tl}
%    \backlayer{%
%      \optbox[extnode=t](A)(B)\psdot(\oenodeExt{})\uput[90](\oenodeExt{}){t}
%      \optbox[extnode=tr](A)(B)\psdot(\oenodeExt{})\uput[90](\oenodeExt{}){tr}
%      \optbox[extnode=r](A)(B)\psdot(\oenodeExt{})\uput[45](\oenodeExt{}){r}
%      \optbox[extnode=br](A)(B)\psdot(\oenodeExt{})\uput[-90](\oenodeExt{}){br}
%      \optbox[extnode=b](A)(B)\psdot(\oenodeExt{})\uput[-90](\oenodeExt{}){b}
%      \optbox[extnode=bl](A)(B)\psdot(\oenodeExt{})\uput[-90](\oenodeExt{}){bl}
%      \optbox[extnode=l](A)(B)\psdot(\oenodeExt{})\uput[135](\oenodeExt{}){l}
%      \optbox[extnode=c](A)(B)\psdot(\oenodeExt{})\uput[180](\oenodeExt{}){c}
%    }
% \end{pspicture}
%
% \choitem[abs]{extnodealign}{rel,relative,abs,absolute}
% \ifGERMAN
% Die Bezeichnung von «oben» (\opt{t}) und den anderen Positionierungsparametern
% von \Lkeyword{extnode} können absolut oder relativ zur Komponente betrachtet
% werden.
%
% In dem folgenden Beispiel ist der externe Knoten immer «oben rechts»
% (\opt{tr}) platziert, unabhängig von der Reihenfolge der Referenzknoten
% (\opt{extnodealign=abs}). Das Verhalten ist identisch zu
% \Lkeyword{labelref}\opt{=relative} für die Ausrichtung der Beschriftung.
% \fi
% \ifENGLISH 
% The definition of «top» (\opt{t}) and the other \Lkeyword{extnode} refpoint
% parameters can be absolute or relative to the component.
%
% In the following example the external node is always placed «top right»
% independent of the actual order of the reference nodes
% (\opt{extnodealign=abs}). The behaviour is identical to the label rotation for
% \Lkeyword{labelref}\opt{=relative}.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]extnodealign}]
\begin{pspicture}(-2,-2)(2,2)
  \psset{endbox, optboxsize=1 0.6, dotscale=1.5}
  \psset{extnodealign=abs, extnode=tr}
  \multido{\i=0+45}{8}{%
    \optbox[innerlabel](0,0)(1;\i){\i}
    \psdot(\oenodeExt{})
  }
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN
% In dem darauffolgenden Beispiel bezieht sich die Positionierung relativ zur
% Verbindung zwischen Eingangs- und Ausgangsreferenzknoten
% (\opt{extnodealign=rel}).
% \fi
% \ifENGLISH
% In the next example the position is relative to the order of input and output
% reference node (\opt{extnodealign=rel}).
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]extnodealign}]
\begin{pspicture}(-2,-2)(2,2)
  \psset{endbox, optboxsize=1 0.6, dotscale=1.5}
  \psset{extnodealign=rel, extnode=tr}
  \multido{\i=0+45}{8}{%
    \optbox[innerlabel](0,0)(1;\i){\i}
    \psdot(\oenodeExt{})
  }%
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
%
% \ifGERMAN\section{Grenzflächenknoten}\fi
% \ifENGLISH\section{Interface nodes}\fi
% \label{sec:ifcnode}
%
% \begin{ltxsyntax}
%   \cmditem{oenodeIfc}{num}{comp}
%
%   \ifGERMAN
%   Der Grenzflächenknoten \prm{num}, wobei \prm{num} eine positive Ganzzahl
%   oder \opt{N} ist. Der letzte Knoten ist immer \opt{N}.
%   \fi
%   \ifENGLISH
%   The interface node \prm{num}, where the number is a positive integer or
%   \opt{N}. The last node is always defined as \opt{N}.
%   \fi
%
%   \cmditem{oenodeIn}{comp}
%
%   \ifGERMAN
%   Der Knoten \prm{1} ist der Eingangsknoten und sollte immer über
%   \nxLcs{oenodeIn} angesprochen werden.
%   \fi
%   \ifENGLISH
%   The interface node \prm{1} is the input node and should always be accessed
%   via \nxLcs{oenodeIn}.
%   \fi
%
%   \cmditem{oenodeOut}{comp}
%
%   \ifGERMAN
%   Der Knoten \opt{N} ist der Ausgangsknoten und sollte
%   immer über \nxLcs{oenodeOut} angesprochen werden.
%   \fi
%   \ifENGLISH
%   The interface node \prm{N} is the output node and should always be accessed
%   via \nxLcs{oenodeOut}.
%   \fi
%
%   \ifGERMAN
%   «Eingang» und «Ausgang» können nur anhand einer relativen Orientierung
%   definiert werden. Per Definition ist der Eingangsknoten derjenige zu dem ein
%   Lichtstrahl ausgehend vom Referenzknoten \Lcs{oenodeRefA} verläuft. Analog
%   dazu ist die Definition ds Ausgangsknotens. Diese Bezeichnung kann nur für
%   Faserkoppler (siehe \prettyref{sec:coupler-nodes}) und Strahlteiler
%   (\ref{cmd:beamsplitter}) nicht angewendet werden.
%
%   \nxLcs{oenodeIn} ist äquivalent zu \nxLcs{oenodeIfc\{1\}} und
%   \nxLcs{oenodeOut} ist äquivalent zu \nxLcs{oenodeIfc\{N\}}. Die Eingangs-
%   und Ausgangsknoten sollten über die explizit bereitgestellten Makros
%   angesprochen werden, \nxLcs{oenodeIfc} sollte nur für die weiteren
%   Grenzflächenknoten, sofern vorhanden, verwendet werden.
%   \fi
%   \ifENGLISH
%   «Input» and «output» can define only relative orientations. The input node
%   is by definition the node to which a beam coming from the reference node
%   \Lcs{oenodeRefA} is connected to. Correspondingly is the definition of the
%   output node. This definition breaks down only for fiber couplers (see
%   \prettyref{sec:coupler-nodes}) and beamsplitter (\ref{cmd:beamsplitter}).
%
%   \nxLcs{oenodeIn} is equivalent to \nxLcs{oenodeIfc\{1\}} and
%   \nxLcs{oenodeOut} is equivalent to \nxLcs{oenodeIfc\{N\}}. You should use
%   the \nxLcs{oenodeIfc} macro only to access the nodes which are not the input
%   and output nodes as for those explicit macros are provided.
%   \fi
% \end{ltxsyntax}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(2.8,3) 
  \pentaprism[pentaprismsize=1.3](0,1.5)(1.5,1.5)(1.5,0)
  \drawbeam[arrows=->, arrowinset=0, arrowscale=1.5](0,1.5){}(1.5,0)
  \psdot(\oenodeIn{})\uput[135](\oenodeIn{}){1}
  \psdot(\oenodeIfc{2}{})\uput[0](\oenodeIfc{2}{}){2}
  \psdot(\oenodeIfc{3}{})\uput[90](\oenodeIfc{3}{}){3}
  \psdot(\oenodeOut{})\uput[-45](\oenodeOut{}){N}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN
% In \prettyref{sec:overview-ifcnode} finden Sie eine vollständige Liste aller
% Komponenten mit ihren Grenzflächenknoten.
% \fi
% \ifENGLISH
% See \prettyref{sec:overview-ifcnode} for a complete list of all
% components with their interface nodes.
% \fi
%
% \ifGERMAN\section{Referenzknoten für die Rotation}\fi
% \ifENGLISH\section{Rotation reference node}\fi
% \label{sec:rotrefnode}
%
% \begin{ltxsyntax}
%   \cmditem{oenodeRotref}{comp}
%
%   \ifGERMAN 
%   Der Referenzknoten um den eine Komponente mit \Lkeyword{angle} gedreht
%   wird. Die Position des Knotens wird mit dem \Lkeyword{rotateref} Parameter
%   definiert und kann dieselben Werte annehmen wie \Lkeyword{extnode}. Eine
%   vollständige Liste der möglichen Positionen finden Sie in
%   \prettyref{sec:overview-extnode}.
%   \fi
%   \ifENGLISH
%   The node around which a component is rotated by \Lkeyword{angle}. The
%   position is defined with the \Lkeyword{rotateref} parameter and can take the
%   same values as \Lkeyword{extnode}. See \prettyref{sec:overview-extnode} for
%   possible rotation reference nodes of all components.
%   \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[pos=t, linerange={1-2, 6-7, 11-12}]
\begin{pspicture}(0,0.1)(12,1.8) 
  \optbox[angle=20](0.5,1)(4.5,1)
  \psdot(\oenodeRefA{})\uput[-90](\oenodeRefA{}){RefA}
  \psdot(\oenodeRefB{})\uput[-90](\oenodeRefB{}){RefB}
  \psline[style=Refline](\oenodeRefA{})(\oenodeRefB{})
  \psdot(\oenodeRotref{})\uput[-90](\oenodeRotref{}){Rotref}
  \optbox[angle=20, rotateref=bl](7.5,1)(11.5,1)
  \psdot(\oenodeRefA{})\uput[-90](\oenodeRefA{}){RefA}
  \psdot(\oenodeRefB{})\uput[-90](\oenodeRefB{}){RefB}
  \psline[style=Refline](\oenodeRefA{})(\oenodeRefB{})
  \psdot(\oenodeRotref{})\uput[-90](\oenodeRotref{}){Rotref}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
%
% \ifGERMAN\section{Strahlknoten}\fi
% \ifENGLISH\section{Beam nodes}\fi
% \label{sec:beamnode}
%
% \ifGERMAN
% Die Endknoten eines \Lcs{drawbeam} oder \Lcs{drawwidebeam} Kommandos
% können wieder verwendet werden, wenn \Lkeyword{savebeampoints} gesetzt ist.
% \fi
% \ifENGLISH
% The end points of a recent \Lcs{drawbeam} or \Lcs{drawwidebeam} command can
% be reused if \Lkeyword{savebeampoints} is set.
% \fi
% \begin{ltxsyntax}
%   \cmditem{oenodeBeam}{num}
%
%   \ifGERMAN
%   Damit wird der Endknoten eines vorangegangenen \Lcs{drawbeam} Kommandos
%   angesprochen. Wird \prm{num} leer gelassen so wird \opt{1} genommen, was in
%   der Regel dem letzten Strahlengang entspricht. Auf welchen Strahl genau
%   Bezug genommen wird, hängt i.a. von den gewählten Einstellungen von
%   \Lkeyword{savebeampoints} und entsprechender Wahl von \prm{num} ab.
%   \fi
%   \ifENGLISH
%   Access the end point of a preceeding \Lcs{drawbeam} command. If \prm{num} is
%   left empty it defaults to \opt{1} which usually refers to the last beam
%   ray. However, generally it depends on the settings of
%   \Lkeyword{savebeampoints} and the choice of \prm{num} which beam you refer
%   to.
%   \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(0,0)(3,2) 
  \pnode(0,1){A}\pnode(1.6,1){B}
  \optbox[position=end](A)(B)
  \drawbeam[beaminsidelast=false](A){1}
  \psdot(\oenodeBeam{})
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
%   \cmditem{oenodeBeamUp}{num}
%   \cmditem{oenodeBeamLow}{num}
%
%   \ifGERMAN
%   Damit wird der obere («upper») oder untere («lower») Endknoten eines
%   vorangegangenen \Lcs{drawwidebeam} Kommandos angesprochen. Wird \prm{num}
%   leer gelassen so wird \opt{1} genommen, womit man sich in der Regel auf den
%   letzten Strahlengang bezieht. Auf welchen Strahl genau Bezug genommen wird,
%   hängt i.a. von den gewählten Einstellungen von \Lkeyword{savebeampoints} und
%   entsprechender Wahl von \prm{num} ab.
%   \fi
%   \ifENGLISH
%   Access the upper or lower end point of a preceeding \Lcs{drawwidebeam}
%   command. If \prm{num} is left empty it defaults to \opt{1}, which usually
%   refers to the last beam ray. However, generally it depends on the settings
%   of \Lkeyword{savebeampoints} and the choice of \prm{num} which beam you
%   refer to.
%   \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-6,10-10}]
\begin{pspicture}(0,0)(3,2) 
  \pnode(0,1){A}\pnode(3,1){B}
  \lens[abspos=1, lensradius=-2](A)(B)
  \addtopsstyle{Beam}{%
    fillstyle=solid, fillcolor=green, opacity=0.3}
  \drawwidebeam[beamwidth=0.5](A){}(B)
  \psdot(\oenodeBeamUp{})\psdot(\oenodeBeamLow{})
  \uput[90](\oenodeBeamUp{}){\rput[rb](0,0){BeamUp}}
  \uput[-90](\oenodeBeamLow{}){\rput[rt](0,0){BeamLow}}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN
% Beachten Sie, dass «oben» («upper») und «unten» («lower») bezüglich der
% Ausbreitungsrichtung des Strahls definiert ist. Ein Randstrahl der als «upper»
% startet can zu «lower» werden, wenn er den anderen Randstrahl kreuzt. Das wird
% in dem folgenden Beispiel erläutert:
% \fi
% \ifENGLISH
% Note, that «upper» and «lower» is defined with respect to the propagation
% direction of the beam. A marginal beam which started as «upper» can change to «lower»
% if it crosses the other marginal beam. This is shown in the following example,
% where the marginal rays exchange their roles:
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-6,10-10,14-14}]
\begin{pspicture}(0,0)(3,2) 
  \pnode(0,1){A}\pnode(3,1){B}
  \lens[abspos=1, n=2](A)(B)
  \addtopsstyle{Beam}{%
    fillstyle=solid, fillcolor=green, opacity=0.3}
  \drawwidebeam[beamwidth=0.5](A){}
  \psdot(\oenodeBeamUp{})\psdot(\oenodeBeamLow{})
  \uput[90](\oenodeBeamUp{}){\rput[rb](0,0){BeamUp}}
  \uput[-90](\oenodeBeamLow{}){\rput[rt](0,0){BeamLow}}
  \drawwidebeam[loadbeam, beaminsidefirst]{}(B)
  \psdot(\oenodeBeamUp{})\psdot(\oenodeBeamLow{})
  \uput[90](\oenodeBeamUp{}){\rput[rb](0,0){BeamUp}}
  \uput[-90](\oenodeBeamLow{}){\rput[rt](0,0){BeamLow}}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN Bei einer Reflektion können ebenfalls die Rollen vertauscht werden.\fi
% \ifENGLISH After a reflection the roles can also be exchanged.\fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-6,8-8,15-15}]
\begin{pspicture}(0,-1)(4,2)
  \pnode(0,1.5){A}\pnode(2,1.5){B}\pnode(2.8,0){C}
  \mirror[mirrorwidth=1.2, mirrortype=extended](A)(B)(C)
  \addtopsstyle{Beam}{%
    fillstyle=solid, fillcolor=green, opacity=0.3}
  \drawwidebeam[beamwidth=0.5](A){}
  \pnode(\oenodeBeamUp{}){Up1}\pnode(\oenodeBeamLow{}){Low1}
  \drawwidebeam[loadbeam]{}(C)
  \psdot(\oenodeBeamUp{})\psdot(\oenodeBeamLow{})
  \uput[90](\oenodeBeamUp{}){\rput[lb](0,0){BeamUp}}
  \uput[-90](\oenodeBeamLow{}){BeamLow}
  \psdot(Up1)\psdot(Low1)
  \uput[90](Up1){\rput[lb](0,0){BeamUp}}
  \uput[0](Low1){\rput[l](0,0){BeamLow}}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN 
% Beachten Sie, dass sich die Orientierung von «oben» und «unten» in
% Version 3.3 geändert hat, siehe \prettyref{sec:bwd-comp-3.3}.
% \fi
% \ifENGLISH
% Note, that the orientation of «upper» and «lower» changed with version
% 3.3, for more details see \prettyref{sec:bwd-comp-3.3}.
% \fi
% \end{ltxsyntax}
%
% \ifGERMAN
% Die Strahlknoten können nur innerhalb der \Lenv*{pspicture}-Umgebung verwendet
% werden, in der sie definiert wurden. Um auf bestimmte Strahlknoten von
% außerhalb zugreifen zu können müssen diese vorher explizit umdefiniert werden:
% \fi
% \ifENGLISH
% The beam nodes can be accessed only within the \Lenv*{pspicture} environment
% they were defined in. If you want to use one of these nodes from outside, you
% must explicitely redefine them beforehand:
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{lstlisting}
\pnode(\oenodeBeam{}){MyBeamNode}
\end{lstlisting}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN
% Desweiteren werden die Endknoten durch \Lkeyword{stopinside}
% beeinflusst. Siehe \prettyref{sec:custombeam} für weitere Details.
% \fi
% \ifENGLISH
% The end points are also affected by \Lkeyword{stopinside}. See
% \prettyref{sec:custombeam} for further details.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(0,0)(3,2) 
  \pnode(0,1){A}\pnode(1.6,1){B}
  \optbox[position=end](A)(B)
  \psset{beaminsidelast=false}
  \drawbeam[linecolor=red, beampos=0.3](A){1}
  \psdot(\oenodeBeam{})
  \drawbeam[stopinside](A){1}
  \psdot(\oenodeBeam{})
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN\section{Strahlvektor}\fi
% \ifENGLISH\section{Beam vector}\fi
%
% \ifENGLISH In addition to the beam nodes (see
% \prettyref{sec:beamnode}) also the vectors of the last saved beams
% (see \Lkeyword{savebeam}) can be access on Postscript level.
%
% These are again separated in single, upper and lower beams. \prm{num}
% has the same meaning as for \Lcs{oenodeBeam}.
% \fi
%
% \ifGERMAN Zusätzlich zu den Strahlknoten (siehe
% \prettyref{sec:beamnode}) kann auf Postscript-Ebene auf die normierten
% Strahlvektoren der letzten gespeicherten Strahlen (siehe
% \Lkeyword{savebeam}) zugegriffen werden.
%
% Auch hier wird zwischen Einzelstrahlen, und oberem bzw. unterem Strahl
% unterschieden. \prm{num} hat dieselbe Bedeutung wie bei \Lcs{oenodeBeam}.
% \fi
% \begin{ltxsyntax}
%   \cmditem{oeBeamVec}{num}
%   \cmditem{oeBeamVecUp}{num}
%   \cmditem{oeBeamVecLow}{num}
% \end{ltxsyntax}
%
% \ifGERMAN Das kann dazu genutzt werden, um z.B. die Polarisation eines
% Strahls zu kennzeichnen. Im folgenden Beispiel wird ein neuer Knoten
% \prm{C} definiert, indem mit \Lcs*{nodexn} der Endpunkt des Strahls
% entlang seiner Trajektorie verschoben wird.
% \fi
% \ifENGLISH A possible application is marking of the polarization of a
% beam. In the following example we define a node \prm{C} which is
% shifted with \Lcs*{nodexn} from the beam end point along the beam
% trajectory.
% \fi
% 
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-7,9-9}]
\begin{pspicture}(3,3)
  \pnode(0,1.5){A}\pnode(3,1.5){B}
  \lens[abspos=1, lens=5 5 3, n=2.1](A)(B)
  \optplane(B)
  \drawbeam[beampos=1](A){1-2}
  \nodexn{(\oenodeBeam{})-1.5(!\oeBeamVec{})}{C}
  \polarization(C)(\oenodeBeam{})
  \psdot(C)\uput[45](C){C}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN Dieses Beispiel zeigt, dass wirklich der letzte eingehende
% Strahlenvektor genommen wird, im Gegensatz zu \Lkeyword{loadbeam}, wo
% der ausgehende Strahl weiterverwendet wird. Die Richtung des ausgehenden Strahl ist
% rot angedeutet.
% \fi
% \ifENGLISH This examples shows that the last incoming beam vector is
% used, instead of \Lkeyword{loadbeam}, where the outgoing beam vector
% is used. The direction of the outgoing beam is marked red.
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-5,8-8}]
\begin{pspicture}(3,2)
  \pnode(0,1){A}\pnode(3,1){B}
  \optbox[optboxsize=2 1, angle=20](A)(B)
  \drawbeam[beaminsidelast, beamalign=abs](A){1}
  \nodexn{(\oenodeBeam{})-(!\oeBeamVec{})}{C}
  \psdot(C)\uput[-90](C){C}
  \psline[linecolor=red, linestyle=dashed, dash=2pt 2pt, arrows=->, arrowscale=1.5](A|\oenodeBeam{})(B|\oenodeBeam{})
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifENGLISH This can be applied to the upper and lower beams as well.\fi
% \ifGERMAN Das kann ebenfalls auf den oberen und unteren
% Strahl angewendet werden.
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-9,11-11}]
\begin{pspicture}(3,3)
  \pnode(0,1.5){A}\pnode(3,1.5){B}
  \lens[abspos=1, lens=5 5 3, n=2.0](A)(B)
  \optplane[angle=90](B)
  \drawwidebeam[beamwidth=2](A){1-2}
  \nodexn{(\oenodeBeamUp{})-2(!\oeBeamVecUp{})}{U}
  \nodexn{(\oenodeBeamLow{})-2(!\oeBeamVecLow{})}{L}
  \polarization(U)(\oenodeBeamUp{})
  \polarization(L)(\oenodeBeamLow{})
  \psdot(U)\uput[45](U){U}\psdot(L)\uput[-45](L){L}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \ifGERMAN Ein weiteres Beispiel finden Sie in \prettyref{ex:glan-thompson}.\fi
% \ifENGLISH For another example see \prettyref{ex:glan-thompson}.\fi
%
%
% \ifGERMAN\section{Knotenübersicht}\fi
% \ifENGLISH\section{Node overview}\fi
%
% \ifENGLISH This is an overview of all available component nodes.\fi
% \ifGERMAN Dies ist eine Übersicht über alle verfügbaren Komponentenknoten.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[pos=t, linerange={2-4,16-16}]
\psset{unit=2}
\begin{pspicture}(0.3,0.1)(4.8,1.6)
  \pnode(0.5,0.5){A}\pnode(4.5,0.5){B}
  \optbox[compshift=0.5, angle=10, rotateref=tr, extnode={-0.5,1}](A)(B)
  \psline[style=Refline](\oenodeTrefA{})(\oenodeTrefB{})
  \psdot(\oenodeRefA{})\uput[-90](\oenodeRefA{}){RefA}
  \psdot(\oenodeRefB{})\uput[-90](\oenodeRefB{}){RefB}
  \psdot(\oenodeTrefA{})\uput[90](\oenodeTrefA{}){TrefA}
  \psdot(\oenodeTrefB{})\uput[90](\oenodeTrefB{}){TrefB}
  \psdot(\oenodeOut{})\uput[80](\oenodeOut{}){\rput[l](0,0.1){Out}}
  \psdot(\oenodeIn{})\uput[100](\oenodeIn{}){\rput[r](0,0){In}}
  \psdot(\oenodeCenter{})\uput[90](\oenodeCenter{}){Center}
  \psdot(\oenodeRotref{})\uput[90](\oenodeRotref{}){Rotref}
  \psdot(\oenodeExt{})\uput[90](\oenodeExt{}){Ext}
  \psdot(\oenodeLabel{})\uput[90](\oenodeLabel{}){Label}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN\chapter{Verbinden von Komponenten}\fi
% \ifENGLISH\chapter{Connecting components}\fi
% \label{chap:connecting}
% 
% \ifGERMAN 
% Das \nxLPack{pst-optexp}-Paket stellt unterschiedlichen Methoden bereit,
% Komponenten vollautomatisch oder manuell, mit Fasern oder mit Lichtstrahlen zu
% verbinden.
% \begin{compactitem}
% \item In \prettyref{sec:accessobj} wird beschrieben wie Komponenten und Knoten für Verbindungen angesprochen werden.
% \item Strahlverbindungen im Allgemeinen und das Verhalten von Einzelstrahlen wir in \prettyref{sec:drawbeam} beschrieben.
% \item \prettyref{sec:drawwidebeam} erweitert diese Beschreibung von Strahlverbindungen auf ausgedehnte Strahlen.
% \item In \prettyref{sec:error-handling} wird gezeigt, wie fehlerhafte Strahlverbindungen (verfehlen von Grenzflächen) gehandhabt wird).
% \item \prettyref{sec:custombeam} erläutert, wie stückweise definierte Strahlengänge einfach realisiert werden können.
% \item Manuelle und automatische Faserverbindungen werden in \prettyref{sec:drawfiber} behandelt.
% \item \prettyref{sec:layers} erklärt das Konzept der «front» und «back»-Ebene.
% \end{compactitem}
% \fi
% \ifENGLISH
% The \LPack{pst-optexp} package provides several methods for automatic and
% manual beam and fiber drawing.  
% 
% \begin{compactitem}
% \item \prettyref{sec:accessobj} describes how to access objects and nodes for use with connections.
% \item Beam drawing in general and the behavior of single beams is explained in \prettyref{sec:drawbeam}.
% \item \prettyref{sec:drawwidebeam} extends this description of beam drawing to wide beams.
% \item \prettyref{sec:error-handling} shows how errors in beam connections (missed interfaces etc.) are handled.
% \item \prettyref{sec:custombeam} explains how customized, piecewise defined beam paths are constructed.
% \item Manual and automatic fiber connections are described in \prettyref{sec:drawfiber}.
% \item \prettyref{sec:layers} introduces the concept of front and back layer for the drawings.
% \end{compactitem}
% \fi
% \ifGERMAN\section{Zugriff auf Komponenten}\fi
% \ifENGLISH\section{Accessing components}\fi\label{sec:accessobj}
% 
% \ifENGLISH
% All macros for connections can take either an ID, a \Lkeyword{compname}
% identifier (see \prettyref{sec:namingobj}) or PSTricks nodes as arguments,
% which are denoted with \prm{obj$_1$}, \prm{obj$_2$}, \ldots. To distinguish
% between nodes and components, nodes must be either enclosed in parenthesis
% within the brackets, or enclosed only in parenthesis:
% \Lcs{drawbeam}\opt{\{(node)\}\{comp\}}, or \Lcs{drawbeam}\opt{(node)\{comp\}}.
% \fi
% \ifGERMAN
% Alle Makros für Verbindungen akzeptieren entweder eine ID, ein
% \Lkeyword{compname} Bezeichner (siehe \prettyref{sec:namingobj}) oder einen
% PSTricks-Knoten als Argument, die als \prm{obj$_1$}, \prm{obj$_2$}, \ldots{}
% bezeichnet werden. Um zwischen Knoten und Komponenten unterscheiden zu können,
% müssen Knoten entweder in runde Klammern innerhalb der geschweiften Klammern
% eingeschlossen werden oder dürfen nur runde Klammern haben:
% \Lcs{drawbeam}\opt{\{(node)\}\{comp\}}, oder
% \Lcs{drawbeam}\opt{(node)\{comp\}}.
% \fi
%
% \begin{enumerate}
% \item 
%   \ifGERMAN Auf alle Komponenten kann immer unter Verwendung der ID
%   zugegriffen werden.
%   \fi
%   \ifENGLISH All components can always be accessed via their ID.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.5)
  \pnode(0,1){A}\pnode(1.5,1){B}
  \optbox[position=end, labeloffset=0](A)(B){1}
  \drawbeam(A){1}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \item 
%   \ifGERMAN Wenn eine Komponente mit \Lkeyword{compname} einen zusätzlichen
%   Namen erhalten hat, so kann dieser anstelle der ID verwendet werden.
%   \fi
%   \ifENGLISH A component which has been assigned a name with
%   \Lkeyword{compname} can also be accessed via this instead of its ID.
%   \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{compname}}]
\begin{pspicture}(3,2)
  \psset{position=end, labeloffset=0}
  \optbox[compname=obj](0,1)(1.5,1){obj}
  \drawbeam(0,1){obj}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \item
%   \ifGERMAN Wird das Argument leer gelassen, dann greift man auf die zuletzt
%   definierte Komponente zu.
%   \fi
%   \ifENGLISH If the argument is left empty, use the last component defined.
%   \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
  \psset{position=end, labeloffset=0}
  \optbox(0,0.5)(1.5,0.5){1}
  \optbox(0,1.5)(1.5,1.5){2}
  \drawbeam(0,1){}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \item 
% \ifGERMAN 
% Bei \Lcs{drawbeam} und \Lcs{drawwidebeam} können auch Zahlintervalle verwendet
% werden. Gültige Intervallangaben sind
% \begin{description}
% \item[\parbox{2em}{\texttt{x-y}}] Von \opt{x} bis \opt{y}, ist \opt{x}
%   größer als \opt{y}, so wird heruntergezählt. Ist der gesamte
%   Bereich nicht definiert, dann wird ein Fehler ausgegeben.
% \item[\parbox{2em}{\texttt{x-}}] Von \opt{x} bis zur letzten Komponente.
% \item[\parbox{2em}{\texttt{\hphantom{x}-y}}] Von der ersten Komponente
%   bis \opt{y}. Ist \opt{y} außerhalb des definierten Bereichs, dann
%   wird eine Warnung ausgegeben.
% \item[\parbox{2em}{\texttt{\hphantom{x}-}}] Verbinde alle Komponenten.
% \end{description}
% \fi
% \ifENGLISH For \Lcs{drawbeam} and \Lcs{drawwidebeam} you can also specify a
% number range. Valid range specifications are
% \begin{description}
% \item[\parbox{2em}{\texttt{x-y}}] From \opt{x} to \opt{y}, if \opt{x}
%   is greater than \opt{y}, the numbers are decremented. If the whole
%   range is not defined, an error is raised.
% \item[\parbox{2em}{\texttt{x-}}] From \opt{x} to the last component.
% \item[\parbox{2em}{\texttt{\hphantom{x}-y}}] From the first component
%   to \opt{y}. If \opt{y} is outside the valid range, a warning is
%   raised.
% \item[\parbox{2em}{\texttt{\hphantom{x}-}}] Connect all components.
% \end{description}
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,3)
  \psset{position=end, optboxsize=0.5 0.5, bssize=0.5}
  \optbox[compname=obj](0.5,0.5)(0.5,2.5){obj, 1}
  \beamsplitter(0.5,2.5)(0.5,1)(2.5,1){2}
  \optbox(0.5,1)(2.5,1){3}
  \drawbeam{1-3}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{enumerate}
%
% \ifENGLISH\section{Drawing beams}\fi
% \ifGERMAN\section{Strahlen zeichnen}\fi
% \label{sec:drawbeam}
% \ifENGLISH
% The package provides several ways to connect components and nodes with beams,
% which can be either single rays or wide beams. Most parameters have the same
% effect on both single and wide beams so most examples will be shown for
% single beams only. For options specific to wide beams please see
% \prettyref{sec:drawwidebeam}.
% \fi
% \ifGERMAN Es gibt mehrere Möglichkeiten Komponenten und Knoten mit Strahlen zu
% verbinden: einfache Linien oder ausgedehnte Strahlen. Die meisten Parameter
% haben für beide Typen dieselbe Bedeutung, daher beschränken sich die
% entsprechenden Beispiele auf die einfachen Strahlen. Die Parameter die nur
% ausgedehnte Strahlen betreffen, werden in \prettyref{sec:drawwidebeam}
% beschrieben.
% \fi
%
% \begin{ltxsyntax}
%   \xLcs{drawbeam}\cmditem{drawbeam}[options]{obj$_1$}{obj$_2$}\ldots
%   \xLcs{drawwidebeam}\cmditem*{drawwidebeam}[options]{obj$_1$}{obj$_2$}\ldots
%
%   \ifENGLISH
%   These are the two macros for beam connections; they can take a variable
%   number of arguments (minimum of two) which can be either an ID, a
%   \Lkeyword{compname}, or a PSTricks nodes. To distinguish between nodes and
%   components, nodes must be either enclosed in parenthesis within the
%   brackets, or enclosed only in parenthesis:
%   \Lcs{drawbeam}\opt{\{(node)\}\{comp\}}, or
%   \Lcs{drawbeam}\opt{(node)\{comp\}}.
%   \fi
%   \ifGERMAN 
%   Diese beiden Makros sind für die Strahlverbindungen zuständig, sie
%   akzeptieren eine variable Anzahl an Argumenten (mindestens zwei), die
%   entweder eine ID, ein \Lkeyword{compname}, oder ein PSTricks-Knoten sein
%   können. Um zwischen Knoten und Komponenten unterscheiden zu können, müssen
%   Knoten entweder in runde Klammern innerhalb der geschweiften Klammern
%   eingeschlossen werden oder dürfen nur runde Klammern haben:
%   \Lcs{drawbeam}\opt{\{(node)\}\{comp\}}, oder
%   \Lcs{drawbeam}\opt{(node)\{comp\}}.
%   \fi
% \end{ltxsyntax}
%
% \subsection{Raytracing}\label{sec:raytracing}
% \ifENGLISH
% The beam connection macros support two modes of tracing the beam across the
% optical components: one is to use refractive indices and Snell's law to
% determine the beam path. The other mode is to connect the components only,
% regardless of their optical properties.
%
% You must always keep in mind, that this is a package for \emph{sketching}
% experimental setups. Therefore, we do not provide a comprehensive raytracing
% framwork, because deviations from the actual physical path are often desired
% for sketches: beam angles and divergences should be in many cases more extreme
% than in the real setup in order to highlight certain aspects. You should also
% consider the refractive index (see \prettyref{sec:n}) only as a tool to
% optimize the visual effects of the beam path, and not stick with its
% physically correct values.
% \fi
% \ifGERMAN
% Der Strahlengang durch die Komponenten kann mit zwei unterschiedlichen
% Methoden ermittelt werden: über den Brechungsindex und das Snelliussche
% Brechungsgesetz, oder indem die Komponenten unabhängig von ihren optischen
% Eigenschaften einfach verbunden werden.
%
% Behalten Sie immer im Hinterkopf, dass dieses Paket für \emph{Skizzen}
% optischer Aufbauten gedacht ist und daher keine vollständige Umgebung zur
% Strahlverfolgung bereitstellt. Abweichungen vom physikalisch richtigen Weg
% können in vielen Fällen erwünscht sein: Winkel und Divergenzen werden häufig
% extremer dargestellt um bestimmte Effekte hervorzuheben. Daher sollten Sie den
% Brechungsindex (siehe \prettyref{sec:n}) lediglich as Mittel zur Optimierung
% des gewünschten Lichtweges sehen und nicht zu sehr an den physikalisch
% richtigen Werten festhalten.
% \fi
%
% \begin{optionlist}
%   \boolitem[true]{raytrace}
%   \ifENGLISH
%   Chooses the mode of tracing the beam path,
%   \opt{true} uses the refractive index («raytracing»), \opt{false} selects
%   component connection («connect» mode).
%
%   In most cases, the «connect» mode is equivalent to «raytracing» with
%   \Lkeyword{n}\opt{=1}, except for \Lcs{optprism} and \Lcs{doveprism}, where
%   the interface nodes (\prettyref{sec:ifcnode}) are simply connected. 
%   See the following two example for the differences between the tracing modes
%   using these two components. The interface nodes are highlighted for clarity.
%
%   The raytraced beam with \Lkeyword{n}\opt{=1} (blue) passes the component
%   without changing its direction, the refraction for \Lkeyword{n}\opt{=1.5} is
%   calculated (red), and the «connect» beam (green) just passes through the two
%   interface nodes.
%   \fi
%   \ifGERMAN
%   Wählt die Methode der Strahlverfolgung, mit \opt{true} wird der
%   Brechungsindex («raytracing») verwendet, \opt{false} verbindet die
%   Komponente lediglich («connect» Variante).
%
%   In vielen Fällen ist «connect» identisch mit «raytracing» für
%   \Lkeyword{n}\opt{=1}, außer für \Lcs{optprism} oder \Lcs{doveprism} bei
%   denen die Grenzflächenknoten (\prettyref{sec:ifcnode}) dann einfach nur
%   verbunden werden.  Die folgenden beiden Beispiele zeigen die Unterschiede
%   der beiden Methoden für diese Komponenten. Die Grenzflächenknoten sind zum
%   besseren Verständnis hervorgehoben.
%
%   Der «raytracing» Strahl mit \Lkeyword{n}\opt{=1} (blau) wird durch die
%   Komponente transmittiert ohne die Richtung zu verändern, für
%   \Lkeyword{n}\opt{=1.5} (rot) wird die Brechung an den Grenzflächen berechnet,
%   und der «connect» Strahl (grün) durchläuft genau die Grenzflächenknoten.
%   \fi
%
%\iffalse
%<*ignore>
%\fi
\begin{LTXexample}[linerange={1-7,9-9}]
\begin{pspicture}(3,2.2)
  \pnode(0,1.5){A}\pnode(1,1.5){B}\pnode(3,1){C}
  \optprism[prismsize=1.2](A)(B)(C)
  \optplane(C)
  \drawbeam[n=1, linecolor=blue](A){1}{2}
  \drawbeam[n=1.5, linecolor=red](A){1}{2}
  \drawbeam[raytrace=false, linecolor=DGreen](A){1}{2}  
  \psdot(\oenodeIn{1})\psdot(\oenodeOut{1})
\end{pspicture}
\end{LTXexample}
%\iffalse
%</ignore>
%\fi
%
% \ifENGLISH
% For the \Lcs{doveprism} the same applies as for the \Lcs{optprism}, but the
% raytraced beam with \Lkeyword{n}\opt{=1} (blue) misses the second interface
% because it is not refracted and stops therefore at the first interface (see
% \prettyref{sec:error-handling}). Again, the green «connect» ray passes through
% all interface nodes.
% \fi
% \ifGERMAN
% Das \Lcs{doveprism} wird im Prinzip genauso behandelt wie das \Lcs{optprism},
% der «raytracing» Strahl mit \Lkeyword{n}\opt{=1} (blau) trifft wegen fehlender
% Brechung die zweite Grenzfläche gar nicht, und endet daher schon an der ersten
% Grenzflächen (siehe \prettyref{sec:error-handling}). Der grüne «connect»
% Strahl verläuft wieder durch die Grenzflächenknoten.
% \fi
%
%\iffalse
%<*ignore>
%\fi
\begin{LTXexample}[linerange={1-6,8-8}]
\begin{pspicture}(4,2)
  \pnode(0,1){A}\pnode(4,1){B}
  \doveprism[doveprismsize=1](A)(B)
  \drawbeam[n=1, linecolor=blue, beampos=0.1](A){1}(B)
  \drawbeam[n=1.5, linecolor=red](A){1}(B)
  \drawbeam[raytrace=false, linecolor=DGreen](A){1}(B)  
  \psdot(\oenodeIn{1})\psdot(\oenodeIfc{2}{1})\psdot(\oenodeOut{1})
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN 
% Für «connect» können auch unterschiedliche Anfangsbedingungen
% (\ref{prm:beampos}) verwendet werden.
% \fi
% \ifENGLISH
% The «connect» mode also supports changing the initial conditions
% (\ref{prm:beampos}).
% \fi
%\iffalse
%<*ignore>
%\fi
\begin{LTXexample}[linerange={1-7,9-9}, morekeywords={[21]beampos,beamangle}]
\begin{pspicture}(3.7,2)
  \pnode(0,1){A}\pnode(4,1){B}
  \doveprism[doveprismsize=1](A)(B)
  \psset[optexp]{raytrace=false}
  \drawbeam[linecolor=blue, beampos=0.2, beamangle=-10](A){1}(B)
  \drawbeam[raytrace=false, linecolor=DGreen](A){1}(B) 
  \drawbeam[linecolor=red, beampos=-0.2, beamangle=10](A){1}(B)
  \psdot(\oenodeIn{1})\psdot(\oenodeIfc{2}{1})\psdot(\oenodeOut{1})
\end{pspicture}
\end{LTXexample}
\begin{LTXexample}[linerange={1-7,9-9}, morekeywords={[21]beampos,beamangle}]
\begin{pspicture}(3.7,2)
  \pnode(0,1){A}\pnode(4,1){B}
  \doveprism[doveprismsize=1](A)(B)
  \psset[optexp]{raytrace=false}
  \drawbeam[linecolor=blue, beampos=0.2](A){1}(B)
  \drawbeam[linecolor=DGreen](A){1}(B) 
  \drawbeam[linecolor=red, beampos=-0.2](A){1}(B)
  \psdot(\oenodeIn{1})\psdot(\oenodeIfc{2}{1})\psdot(\oenodeOut{1})
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \boolitem[true]{useNA}
% \ifGERMAN Ein Strahlengang wird abgebrochen, falls eine Komponente nicht
% getroffen wird. Für manche Zwecke, z.B. zum Ermitteln des richtigen
% Brechungsindex, kann es sinnvoll sein, wenn die numerische Apertur eine
% Komponente nicht berücksichtigt wird. In dem folgenden Beispiel wird der
% rote Strahl gezeichnet, obwohl er außerhalb der gezeichneten Spiegelfläche
% liegt.
% \fi
% \ifENGLISH The beam path is interrupted if an interface is missed. In some
% cases, e.g. to estimate the correct refractive index for a ray trace, it can
% be useful if the numerical aperture of the components is not considered. The
% red beam in the following example is drawn, although it hits the mirror
% outside the drawn mirror surface.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
  \pnode(0,0.5){A}\pnode(2.5,0.5){B}\pnode(2.5,2){C}
  \mirror(A)(B)(C)
  \psset{useNA=false}
  \drawbeam(A){}(C)
  \drawbeam[linecolor=red, beamangle=10](A){}(C)  
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \end{optionlist}
%
% \ifENGLISH\subsection{Refractive index}\fi
% \ifGERMAN\subsection{Brechungsindex}\fi
% \label{sec:n}
%
% \ifENGLISH
% The raytracing depends on the refractive index, which may be set for each
% component separately. The refractive index is always relative to the
% background which has a constant value for the whole sketch.
% \fi
% \ifGERMAN
% Das Raytracing wird durch den Brechungsindex bestimmt, der für jede Komponente
% einzeln gesetzt werden kann. Der Wert ist relativ zum Hintergrund, für den ein
% konstanter Wert für die gesamte Skizze angenommen wird.
% \fi
%
% \begin{optionlist}
% \valitem[1.5]{n}{code}
% \ifGERMAN 
% Setzt den Brechungsindex relativ zum Hintergrund. Diese Option hat zwei
% Anwendungsbereiche: zum einen kann der Index einer Komponente gesetzt werden,
% zum anderen der Brechungsindex für einen Strahlengang:
% \fi
% \ifENGLISH Sets the relative refractive index respect to the background. This
% parameter has two scopes, you can either set the refractive index of each
% component or of each beam ray: 
% \fi
% \end{optionlist}
%
% \ifGERMAN
% \begin{enumerate}
% \item Wird \Lkeyword{n} als globaler Parameter oder als Komponentenparameter
%   verwendet, so wird der Index für alle betroffenen Komponenten gesetzt. Ohne
%   weitere Änderungen wird jeder Lichtstrahl diese Werte verwenden.
% \item Als Parameter zu \Lcs{drawbeam} oder \Lcs{drawwidebeam} kann der
%   Brechungsindex der Komponenten für einzelne Strahlengänge überschrieben oder
%   geändert werden. Das kann sehr nützlich sein, um z.B. chromatische
%   Dispersion zu illustrieren. Soll die Änderung global für alle oder mehrere
%   Lichtstrahlen wirksam sein, so muss der gewünschte Wert dem
%   \Lstyle{Beam}-Stil hinzugefügt werden, da globale Definitionen von
%   \Lkeyword{n} nur die Komponenten betreffen.
% \end{enumerate}
% \fi
% \ifENGLISH
% \begin{enumerate}
% \item Using \Lkeyword{n} as global parameter or component argument
%   sets a fixed refractive index for each affected component. Without further
%   actions, all beam paths experience this refractive index.
% \item As parameter for \Lcs{drawbeam} or \Lcs{drawwidebeam} you can overwrite
%   or even change the refractive index of the components for specific beam
%   paths. This can be very useful e.g. to simulate chromatic dispersion. To set
%   this globally for all beams you must add the respective parameter
%   definition to the \Lstyle{Beam} style because global definitions of
%   \Lkeyword{n} affect only the components and not the beams.
% \end{enumerate}
% \fi
%
% \ifENGLISH
% The \prm{code} can in general be any Postscript code which evaluates to a
% number, e.g. \opt{1.5}, or \opt{5 sqrt}. If the \prm{code} starts with a
% \opt{*}, it will be interpreted as an algebraic
% expression\fnurl{http://mirror.ctan.org/graphics/pstricks/base/doc/pst-news08.pdf},
% e.g. \opt{*sqrt(5)} is equivalent to \opt{5 sqrt}. Inside the \prm{code} you
% can access the predefined refractive index of the component via \opt{n} which
% allows you to change the index relative to its original value. Use
% e.g. \opt{n=n 1.01 mul} to change \opt{n} by one percent.
%
% In the following you find several examples about the different aspects of
% using \Lkeyword{n}.
% \fi
% \ifGERMAN
% Der \prm{code} kann jeglicher Postscript-Kode sein, der zu einer Zahl
% ausgewertet werden kann, also z.B. \opt{1.5} oder \opt{5 sqrt}. Beginnt
% \prm{code} mit einem \opt{*}, so wird der Code als algebraischer
% Ausdruck\fnurl{http://mirror.ctan.org/graphics/pstricks/base/doc/pst-news08.pdf}
% ausgewertet, d.h. \opt{*sqrt(5)} ist äquivalent zu \opt{5 sqrt}. Innerhalb von
% \prm{code} kann mit \opt{n} auf den vordefinierten Brechungsindex der
% Komponenten zugegriffen werden, es kann also eine Änderung relativ zum
% ursprünglichen Wert erzielt werden. Mit \opt{n=n 1.01 mul} kann \opt{n}
% z.B. um ein Prozent geändert werden.
%
% In den folgenden Beispielen werden diese unterschiedlichen Möglichkeiten von
% \Lkeyword{n} gezeigt.
% \fi
%
% \begin{enumerate}
% \item 
%   \ifENGLISH Set a fixed refractive index for the component. Interestingly,
%   for the default shape of the \Lcs{doveprism} a refractive index of
%   $\sqrt{5}$ gives the ideal output direction which is the same as the input
%   direction.
%   \fi
%   \ifGERMAN
%   Setze den Brechungsindex einer Komponente. Interessanterweise ist für die
%   Standardform des \Lcs{doveprism} ein Brechungsindex von $\sqrt{5}$ der
%   ideale Wert so dass der Ausgangsstrahl parallel zum Eingangsstrahl verläuft.
%   \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample} 
\begin{pspicture}(3,1.5)
  \pnode(0,1){A}\pnode(3,1){B}
  \doveprism[n=*sqrt(5)](A)(B)
  \drawbeam(A){}(B)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \item 
%   \ifENGLISH In this example one beam uses the default refractive index of the
%   components (green), the other one overwrites it with a value of \opt{2}
%   (red).
%   \fi
%   \ifGERMAN
%   Ein Strahl (grün) verwendet die voreingestellten Werte der Komponenten, der
%   rote überschreibt diese mit \opt{2}.
%   \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords = {[21]{n}}]
\begin{pspicture}(3,3)
  \pnode(0,1){A}\pnode(3,1){B}
  \optplane(A)
  \psset{lens=3 3 2, n=1.5}
  \lens[abspos=0.5](A)(B)
  \lens[abspos=2](A)(B)
  \optplane(B)
  \addtopsstyle{Beam}{beampos=0.5}
  \drawbeam{-}
  \drawbeam[linecolor=red, n=2]{-}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \item 
%   \ifENGLISH 
%   Now, the red beam uses the default refractive index of the component, the
%   yellow beam adds \opt{0.5} to the default index.
%   \fi
%   \ifGERMAN
%   Der rote Strahl verwendet die voreingestellten Werte, der grüne ändert diese
%   um \opt{0.5}.
%   \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords = {[21]{n}}]
\begin{pspicture}(3,3)
  \pnode(0,1.5){A}\pnode(3,1.5){B}
  \lens[lens=4 4 3, n=2, abspos=0.3](A)(B)
  \optplane[compname=Plane](B)
  \psset{beampos=0.6}
  \drawbeam[linecolor=red](A){1}{Plane}
  \drawbeam[linecolor=yellow, n=*(n+0.5)](A){1}{Plane}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \item 
%   \ifENGLISH 
%   Dynamically changing the refractive index is very useful to emulate
%   chromatic dispersion. Here, we sketch the dispersion of a prism by
%   calculating the refractive index with Sellmaier's
%   equation\fnurl{http://en.wikipedia.org/wiki/Sellmeier_equation} for
%   different wavelengths.
%   \fi
%   \ifGERMAN
%   Mit dynamischer Anpassung von \Lkeyword{n} kann chromatische Dispersion sehr
%   gut emuliert werden. Hier wird die Dispersion eines Prisma gezeigt, der
%   Brechungsindex wird mit der Sellmaier
%   Gleichung\fnurl{http://en.wikipedia.org/wiki/Sellmeier_equation} für die
%   unterschiedlichen Wellenlängen berechnet. 
%   \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords = {[21]{n}}]
\begin{pspicture}(3,3)
  \pnode(-1,0){A}\pnode(1,2.2){B}\pnode(3,0){C}
  \optplane(0,2.15)
  \optprism[prismalign=center, prismangle=59](A)(B)(C)
  \optplane(C)
  \definecolor[ps]{bl}{rgb}{%
    tx@addDict begin Red Green Blue end}%
  \addtopsstyle{Beam}{linecolor=bl, linewidth=0.4\pslinewidth, beamalign=abs}
  \multido{\i=0+1}{60}{%
    \pstVerb{%
      \i\space 650 400 sub 59 div mul 400 add 
      tx@addDict begin wavelengthToRGB end }%
    \drawbeam[n=\i\space 650 400 sub 59 div mul 400 add Sellmaier]{-}%
  }%
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \item 
% \ifENGLISH Using the numerical aperture of a pinhole as spectral filter.\fi
% \ifGERMAN Die numerische Apertur einer Lochblende als spektraler Filter.\fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords = {[21]{n}}]
\begin{pspicture}(0.3,0)(3.3,5.2)
  \pnode(0.3,1){A}\pnode(2,1){B}\pnode(3,2){C}\pnode(2.5,5){D}
  \optplane(A)
  \optgrating[reverse](A)(B)(C)
  \pinhole[phwidth=-0.1, innerheight=0.03, abspos=0.5](D)(B)
  \optplate[position=end, plateheight=1.5](B)(D)
  \definecolor[ps]{bl}{rgb}{%
    tx@addDict begin Red Green Blue end}%
  \drawbeam[linecolor=red]{1-2}
  \addtopsstyle{Beam}{linecolor=bl, linewidth=0.4\pslinewidth}
  \multido{\i=0+1}{60}{%
    \pstVerb{%
      \i\space 650 400 sub 59 div mul 400 add 
      tx@addDict begin wavelengthToRGB end }%
    \drawbeam[beamangle=\i\space 0.1 mul 3 sub]{2-}%
  }%
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{enumerate}
%
% \begin{optionlist}
%   \valitem{refractiveindex}{code}
%   \deprecatedmsg{\Lkeyword{n}}
% \end{optionlist}
%
% \ifENGLISH\subsection{Initial conditions}\fi
% \ifGERMAN\subsection{Anfangsbedingungen}\fi
%
% \begin{optionlist}
% \optitem[0]{beampos}{[\prm{x} ]\prm{y}}
% \ifENGLISH
% This is the start position (\prm{x}, \prm{y}) of the beam at the first
% interface. Both values are of \prm{psnum} type. If a single number is given,
% the $x$-coordinate is set to \opt{0}.
% \fi
% \ifGERMAN
% Die Startposition (\prm{x}, \prm{y}) des Strahls an der ersten
% Grenzfläche. Beide Zahlen sind vom Typ \prm{psnum}. Wird eine einzelne Zahl
% angegeben, wird die $x$-Koordinate auf \opt{0} gesetzt.
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords = {[21]{beampos}}]
\begin{pspicture}(4,3.8)
  \pnode(1.5,0.5){A}\pnode(3.5,0.5){B}\pnode(3.5,3.5){C} 
  \optbox[position=end](B)(A)
  \mirror[mirrortype=extended, mirrorradius=3](A)(B)(C)
  \optplate[position=end](B)(C)
  \drawbeam[linecolor=red, beampos=-0.2]{1-3}
  \drawbeam[linecolor=blue, beampos=0]{1-3}
  \drawbeam[linecolor=green, beampos=0.2]{1-3}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifENGLISH The start position is relative to the respective interface node, as
% it is illustrated in the following example. The beam start position is fixed,
% but depending on e.g. the \Lkeyword{beamangle}, the actual intersection with
% the curved interface is at a different position.
% \fi
% \ifGERMAN
% Die Startposition ist relativ zum entsprechenden Grenzflächenknoten, wie im
% folgenden Beispiel gezeigt wird. Die Startposition ist fest, abhängig z.B. von
% \Lkeyword{beamangle} kann der eigentliche Schnittpunkt mit der ersten
% Grenzfläche jedoch anders sein.
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-7,9-9}, morekeywords = {[21]{beampos}}, explpreset={escapeinside={}}]
\begin{pspicture*}(0,2)(3.05,6)
  \lens[lens=8 8 8, abspos=0.6](0.5,2)(3,2)
  \optplate[position=1, plateheight=6](0.5,2)(3,2)
  \psset{beampos=2.1}
  \drawbeam[beamangle=-60]{1}{2}
  \drawbeam[beamangle=-40]{1}{2}
  \drawbeam[beamangle=-20]{1}{2}
  \psline[style=Refline, linewidth=3\pslinewidth, arrows=->, arrowinset=0, arrowscale=1.3](\oenodeOut{1})([offset=2.1]\oenodeOut{1})
\end{pspicture*}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifENGLISH
% Which interface the beam starts at is determined by the options
% \Lkeyword{beaminsidefirst} and \Lkeyword{startinside}.
% \fi
% \ifGERMAN
% An welcher Grenzfläche der ersten Komponente gestartet wird hängt von
% \Lkeyword{beaminsidefirst} und \Lkeyword{startinside} ab.
% \fi
%
% \psnumitem[0]{beamangle}
% \ifGERMAN
% Der Anfangswinkel des Strahls. Dieser ist in der Regel relativ zu der
% Verbindung von der ersten zur zweiten Komponente, mit \Lkeyword{beamalign}
% kann dieses Verhalten verändert werden.
% \fi
% \ifENGLISH
% This is the start angle of the beam. Usually, it is relative to the connection
% between the first two components, use \Lkeyword{beamalign} to change this.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords = {[21]{beamangle}}]
\begin{pspicture}(4,4)
  \pnode(1.5,0.5){A}\pnode(3.5,0.5){B}\pnode(3.5,3.5){C} 
  \optbox[position=end](B)(A)
  \mirror[mirrortype=extended](A)(B)(C)
  \optplate[position=end](B)(C)
  \drawbeam[linecolor=red, beamangle=3]{-3}
  \drawbeam[linecolor=blue, beamangle=0]{1-}
  \drawbeam[linecolor=green, beamangle=-3]{-}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \choitem[relative]{beamalign}{rel, relative, abs, absolute}
% \ifGERMAN
% Gibt vor, ob der Winkel \Lkeyword{beamangle} relativ zu der Verbindung
% zwischen den ersten beiden Komponenten ist, oder ob es sich um einen absoluten
% Winkel handelt.
%
% Ein absoluter Winkel kann sehr hilfreich sein, falls eine der beiden ersten
% Komponenten gedreht oder verschoben wurde. Dabei werden die
% Grenzflächenknoten, auf die sich ein relativer Winkel bezieht, ebenfalls
% transformiert (siehe \prettyref{sec:rotshift}). In dem folgenden Beispiel
% verläuft daher der grüne Strahl mit der relativen Ausrichtung nicht
% horizontal.
% \fi
% \ifENGLISH
% Select whether the \Lkeyword{beamangle} is relative to the connection between
% the first two components, or if it is an absolute angle.
%
% A typical situation where an absolute angle is helpful is with rotated or
% shifted components. By rotating or shifting a component also its interface
% nodes are rotated (see \prettyref{sec:rotshift}) which are then used to
% determine the input angle for relative alignment. Accordingly, in the
% following example, the green beam with the relative alignment is not
% horizontal.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords = {[21]{beamalign, angle}}]
\begin{pspicture}(3,1.5)
  \pnode(0,0.75){A}\pnode(3,0.75){B}
  \optbox[angle=10, showifcnodes](A)(B)
  \drawbeam(A){}(B)
  \drawbeam[linecolor=red, beamalign=abs](A){}(B)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \numitem[0]{beampathskip}
% \ifGERMAN
% Überspringt \prm{num} Segmente am Anfang des Strahlengangs.
% \fi
% \ifENGLISH
% Skip \prm{num} segments at the beginning of the beam path. 
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords = {[21]{beampathskip}}, pos=t]
\begin{pspicture}(5,2)
\pnode(0,1){A}\pnode(5,1){B}\pnode(2,0){C}
\begin{optexp}
  \glanthompson(A)(B)
  \optplane(B)\optplane[angle=90](C)
  \polarization[abspos=1, poltype=misc, linecolor=yellow!80!black](A)(B)
  \drawbeam[beaminsidelast, linecolor=yellow!80!black](A){1}
  \drawbeam[beampathskip=2](A){1-2}
  \drawbeam[beampathskip=2, savebeam, linestyle=dashed, dash=2pt 2pt, linecolor=red,arrowscale=1.5, arrows=->](A){1}{3}
\end{optexp}
\nodexn{(\oenodeBeam{})-1.5(!\oeBeamVec{})}{D}
\polarization[poltype=parallel, linecolor=red](D)(\oenodeBeam{})
\polarization[abspos=4, poltype=perp, linecolor=green, dotscale=1.5](A)(B)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
%
% \ifGERMAN\subsection{Interner Strahlengang}\fi
% \ifENGLISH\subsection{Internal beam path}\fi
%
% \ifENGLISH
% A beam path is composed of rays between components and rays inside the
% components. Depending on some options these internal beams can be drawn or
% not. Generally, the first, the last, and all other components are treated
% separately.
% \fi
% \ifGERMAN
% Ein Strahlengang setzt sich aus Strahlen zwischen den Komponenten und
% innerhalb der Komponenten zusammen. Ob diese internen Strahlen gezeichnet
% werden, kann mit mehreren Parametern festgelegt werden. Die erste, letzte und
% die übrigen Komponenten werden separat gehandhabt.
% \fi
%
% \begin{optionlist}
% \boolitem[true]{beaminside}
% \ifGERMAN
% Zeichnet den Strahlengang innerhalb aller Komponenten mit Ausnahme der
% ersten und letzten, die von dieser Option nicht beeinflusst.
% \fi
% \ifENGLISH
% Draw the internal beams in all intermediate components, the first and last
% components are not affected.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords = {[21]{beaminside}}]
\begin{pspicture}(0.3,0.3)(3,4)
  \psset{optboxwidth=1}
  \optbox[position=end](1,1)(1,3)
  \optretplate(1,1)(1,3)
  \pentaprism(1,3)(1,1)(2,1)
  \optbox[position=end](1,1)(2,1)
  \drawbeam[beampos=-0.05, linecolor=red]{-}
  \drawbeam[beampos=0.05, beaminside=false]{-}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \boolitem[false]{beaminsidefirst}
% \ifGERMAN
% Zeichne den Strahlengang innerhalb der ersten Komponenten.
% \fi
% \ifENGLISH
% Draw the internal beams of the first component.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords = {[21]{beaminsidefirst}}]
\begin{pspicture}(0.3,0.3)(3,4)
  \psset{optboxwidth=1}
  \optbox[position=end](1,1)(1,3)
  \optretplate(1,1)(1,3)
  \pentaprism(1,3)(1,1)(2,1)
  \optbox[position=end](1,1)(2,1)
  \drawbeam[beampos=-0.05, linecolor=red]{-}
  \drawbeam[beampos=0.05, beaminsidefirst]{-}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \boolitem[false]{beaminsidelast}
% \ifGERMAN
% Zeichne den Strahlengang innerhalb der letzten Komponenten.
% \fi
% \ifENGLISH
% Draw the internal beams of the last component.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords = {[21]{beaminsidelast}}]
\begin{pspicture}(0.3,0.3)(3,4)
  \psset{optboxwidth=1}
  \optbox[position=end](1,1)(1,3)
  \optretplate(1,1)(1,3)
  \pentaprism(1,3)(1,1)(2,1)
  \optbox[position=end](1,1)(2,1)
  \drawbeam[beampos=-0.05, linecolor=red]{-}
  \drawbeam[beampos=0.05, beaminsidelast]{-}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \boolitem[true]{allowbeaminside}
% \ifGERMAN
% Damit kann bestimmt werden, ob der Strahlengang innerhalb einer Komponente
% gezeichnet werden darf. Dieser Parameter wirkt nur auf Komponenten und
% überschreibt, falls auf \opt{false} gesetzt, jegliche Strahleinstellungen mit
% \Lkeyword{beaminside}, \Lkeyword{beaminsidefirst} und
% \Lkeyword{beaminsidelast}. Damit kann der Strahlengang in einzelnen
% Komponenten unterdrückt werden, für die es keinen Sinn macht
% (z.B. \Lcs{optfilter} und \Lcs{optdiode}, was sonst nicht möglich ist. 
% \fi
% \ifENGLISH
% Define whether a beam is drawn inside a component. The option affects
% components only and overwrites all settings of \Lkeyword{beaminside},
% \Lkeyword{beaminsidefirst}, and \Lkeyword{beaminsidelast} if set to
% \opt{false}. With this you can forbid any internal beams for components where
% it does not make any sense (e.g. \Lcs{optfilter} and \Lcs{optdiode}).
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords = {[21]{allowbeaminside}}]
\begin{pspicture}(3,2)
  \psset{optboxwidth=0.5}
  \pnode(0,1){A}\pnode(3,1){B}
  \optbox[position=0.2](A)(B)
  \optbox[position=0.4, allowbeaminside=false](A)(B)
  \optbox[position=0.6](A)(B)
  \optbox[position=0.8](A)(B)
  \drawbeam(A){-}(B)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \boolitem[false]{forcebeaminside}
% \ifGERMAN
% Wenn auf \opt{true} gesetzt, wird der Strahlengang innerhalb der
% betroffenen Komponenten immer gezeichnet wird, unabhängig von allen
% anderen Strahleinstellungen mit \Lkeyword{allowbeaminside},
% \Lkeyword{beaminside}, \Lkeyword{beaminsidefirst} und
% \Lkeyword{beaminsidelast}. Damit kann der Strahl innerhalb einzelner
% Komponenten gezeichnet werden, auch wenn alle anderen Komponenten in
% dem Strahlengang keinen internen Strahl haben sollen.
% \fi
% \ifENGLISH
% Forces to draw a beam inside a component. The option affects
% components only and overwrites all settings of
% \Lkeyword{allowbeaminside}, \Lkeyword{beaminside},
% \Lkeyword{beaminsidefirst}, and \Lkeyword{beaminsidelast} if set to
% \opt{true}. With this you can force an internal beams for single
% components within a beam path.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords = {[21]{forcebeaminside}}]
\begin{pspicture}(3,2)
  \psset{optboxwidth=0.5}
  \pnode(0,1){A}\pnode(3,1){B}
  \optbox[position=0.2](A)(B)
  \optbox[position=0.4, forcebeaminside](A)(B)
  \optbox[position=0.6](A)(B)
  \optbox[position=0.8](A)(B)
  \drawbeam[beaminside=false](A){-}(B)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
%
% \ifENGLISH\subsection{Connecting with nodes}\fi
% \ifGERMAN\subsection{Verbinden mit Knoten}\fi
%
% \ifENGLISH
% As mentioned earlier in this chapter, beams can connect components also with
% nodes. For raytracing you need in general a plane, which imposes some problems
% when connecting with nodes. This is handled such, that a temporary plane is
% constructed, which goes through the specified node and is perpendicular to the
% connection between the node and the preceeding component. If a beam starts
% with a node, the orientation is determined by the node and the following
% component.
% \fi
% \ifGERMAN
% Wie vorher schon einmal erwähnt können Komponenten auch mit Knoten verbunden
% werden. Für Raytracing wird in der Regel eine Ebene benötigt, was ein Problem
% hinsichtlich der Knoten darstellt. Das wird so gehandhabt, das eine temporäre
% Ebene definiert wird, die durch den Knoten verläuft und vertikal zur
% Verbindung zwischen dem Knoten und der vorangegangenen Komponente steht. Fängt
% ein Strahlengang mit einem Knoten an, so wird die Ausrichtung durch den Knoten
% und die folgende Komponente bestimmt.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
  \pnode(0,1){A}\pnode(2.5,1){B}
  \lens[lens=3 3 2, n=2.5, abspos=0.5](A)(B)
  \multido{\r=-0.3+0.3}{3}{%
    \drawbeam[beampos=\r](A){}(B)}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifENGLISH
% This is very handy in many cases, but does not allow to rotate the node planes
% and can give again problems with shifted and rotated components (see
% \prettyref{sec:rotshift}).
% For more flexibility, the package provides an «invisible» plane which can be
% used for this purpose.
% \fi
% \ifGERMAN
% Das ist in vielen Fällen sehr praktisch, kann aber wiederum unerwünschte
% Ergebnisse bei gedrehten und verschobenen Komponenten ergeben und die
% Ebenenausrichtung kann nicht beliebig gesetzt werden.  Das kann mit einer
% unsichtbaren Ebene erreicht werden, die mit \Lcs{optplane} definiert wird.
% \fi
%
% \begin{ltxsyntax}
%   \xLcs{optplane}\cmditem{optplane}(center) 
%
%   \ifENGLISH
%   The plane is defined by a single node only, the rotation around this node
%   is defined with \Lkeyword{angle}. The angle is with respect to the default
%   alignment, which is vertical.
%   \fi
%   \ifGERMAN Die Ebene wird durch lediglich einen Knoten definiert, die Drehung
%   darum kann mit \Lkeyword{angle} angegeben werden. Der Winkel ist relativ zur
%   ursprünglichen, vertikalen Ausrichtung.
%   \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
  \pnode(0,1){A}\pnode(2.5,1){B}
  \lens[lens=3 3 2, n=2.5, abspos=0.5](A)(B)
  \optplane[angle=-30](B)
  \multido{\r=-0.3+0.3}{3}{%
    \drawbeam[beampos=\r](A){-}}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
%
% \ifENGLISH\subsection{Automatic connection}\fi
% \ifGERMAN\subsection{Automatische Verbindungen}\fi
%
% \ifENGLISH
% Beam can also be drawn at definition time of a component, which can be handy,
% but allows only very elemental beams.
% \fi
% \ifGERMAN Lichtstrahlen können auch zusammen mit der Komponentendefinition
% gezeichnet werden. Das kann für einfache Strahlengänge sehr praktisch sein,
% ist aber sehr unflexibel.
% \fi
%
% \begin{optionlist}
% \boolitem[false]{beam}
% \ifGERMAN Kann als Option für jede Komponente verwendet werden, ist äquivalent
% zu
% \fi
% \ifENGLISH Can be used as option for every component, is equivalent to the
% statement
% \fi
% \begin{lstlisting}[gobble=2]
% \drawbeam[raytrace=false](\oenodeRefA{}){}(\oenodeRefB{})
% \end{lstlisting}
% \ifENGLISH which draws a beam from one reference node via the component to the
% other reference node.
% \fi 
% \ifGERMAN womit ein Strahl vom ersten Referenzknoten über die Komponente zum
% zweiten Referenzknoten gezeichnet wird.
% \fi
%
% \valitem{conn}{string}
% \ifGERMAN Diese Option wird nur aus Kompatibilitätsgründen bereitgestellt
% und wird aus zukünftigen Versionen entfernt. Siehe
% \prettyref{sec:bwd-comp-3.0} für weitere Informationen.
% \fi
% \ifENGLISH This option is maintained for backward compatibility only and will
% be removed in future versions. See \prettyref{sec:bwd-comp-3.0} for further
% information.
%\fi
% \end{optionlist}
%
% \ifENGLISH\subsection{Beam appearance}\fi
% \ifGERMAN\subsection{Strahlaussehen}\fi
% \label{sec:beamappearance-single}
%
% \begin{stylelist}
%   \styleitem[linecolor=green!90!black, linejoin=1]{Beam}
%   \ifENGLISH
%   The appearance of beams is controlled with this style. The optional argument
%   of \Lcs*{draw*beam} can also be used, these options can overwrite settings from
%   the \Lstyle{Beam} style.
%   \fi
%   \ifGERMAN
%   Das Aussehen der Lichtstrahlen kann mit diesem Stil gesteuert werden. Das
%   optionale Argument von \Lcs*{draw*beam} kann ebenfalls dafür verwendet
%   werden und kann die Einstellungen des \Lstyle{Beam}-Stils überschreiben.
%   \fi
% \end{stylelist}
%
% \begin{optionlist}
%   \valitem{addtoBeam}{list}
%     \addtostylemsg{Beam}
%   \valitem{newBeam}{list}
%     \newstylemsg{Beam}
%
%   \psnumitem[0.2]{ArrowInsideMinLength}
%   \ifGERMAN 
%   \Lcs*{draw*beam} verwendet auch die Option \Lkeyword*{ArrowInside} aus
%   \LPack{pstricks-add}. In dem Fall wird für alle Strahlsegmente ein Pfeil
%   gezeichnet, was häufig für die internen, kurzen Strahlengänge unerwünscht
%   ist. Mit \Lkeyword{ArrowInsideMinLength} kann angegeben werden ab welcher
%   Mindestlänge eines Strahlsegmentes die Pfeil gezeichnet werden. In dem
%   folgenden Beispiel ist der Wert so gewählt, dass nur der untere interne
%   Strahl einen Pfeil hat (siehe auch \prettyref{ex:czerny-turner}).
%   \fi
%   \ifENGLISH 
%   \Lcs*{draw*beam} uses also the option \Lkeyword*{ArrowInside} from
%   \LPack{pstricks-add}. In this case the arrows would be drawn for every beam
%   segment, which is often undesired for the internal, short beam
%   paths. \Lkeyword{ArrowInsideMinLength} sets a minimum segment length, below
%   which no internal arrows are drawn. In the following example the value is
%   selected such that only the lower internal beam has an arrow (see also
%   \prettyref{ex:czerny-turner}).
%   \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{ArrowInsideMinLength}}]
\begin{pspicture}(3,2)
  \optprism(0,1)(2,1)(3,0.5)
  \drawwidebeam[beamwidth=0.4, ArrowInside=->, ArrowInsideMinLength=0.5, arrowscale=1.5, raytrace=false](0,1){}(3,0.5)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \psnumitem[-1]{ArrowInsideMaxLength}
% \ifGERMAN Gibt analog zu \Lkeyword{ArrowInsideMinLength} die maximale Länge
% eines Segments an, für das Pfeile gezeichnet werden. Ist der Wert negativ,
% dann gibt es keine obere Grenze.
% \fi
% \ifENGLISH Like \Lkeyword{ArrowInsideMaxLength}, but sets the maximum length
% of a segment for which the arrows are drawn. If the value is negative, no
% upper limit is defined.
% \fi
% \end{optionlist}
% 
% \ifGERMAN \Lkeyword*{ArrowInside} kann auch verwendet werden ohne dass
% ein Linientyp definiert ist.
% \fi
% \ifENGLISH \Lkeyword*{ArrowInside} can be used also without a
% linestyle.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(0,0)(3.5,2)
  \pnode(0,1.5){A}\pnode(2,1.5){B}\pnode(2.8,0){C}
  \mirror[mirrorwidth=1.2, mirrortype=extended](A)(B)(C)
  \newpsstyle{Beam}{linecolor=green, linestyle=none, fillstyle=solid, fillcolor=green, opacity=0.2}
  \drawwidebeam[beamwidth=0.5](A){}(C)
  \drawbeam[ArrowInside=->, arrowscale=2.5, ArrowFill=false, linewidth=1.5\pslinewidth, ArrowInsidePos=0.9, ArrowInsideMaxLength=1.8](A){}(C)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN\section{Aufgeweitete Strahlen}\fi
% \ifENGLISH\section{Drawing wide beams}\fi
% \label{sec:drawwidebeam}
%
% \ifENGLISH
% All information about single beams (see \prettyref{sec:drawbeam}) apply to
% wide beams as well. Here, you find all additional information which apply to
% wide beams only.
% \fi
% \ifGERMAN
% Alle Informationen über einfache Strahlen (siehe \prettyref{sec:drawbeam})
% betreffen auch aufgeweitete Strahlen. Hier werden nur zusätzliche
% Einstellmöglichkeiten aufgeweiteter Strahlen behandelt.
% \fi
%
% \begin{ltxsyntax}
%   \xLcs{drawwidebeam}\cmditem{drawwidebeam}[options]{obj$_1$}{obj$_2$}\ldots
% \end{ltxsyntax}
%
% \begin{optionlist}
% \psnumitem[0]{beamwidth}
% \ifENGLISH The initial beam width, measured at the initial position (defined
% with \Lkeyword{beampos}) perpendicular to the beam direction.
% \fi
% \ifGERMAN Die Anfangsstrahlbreite an der mit \Lkeyword{beampos} angegebenen
% Position, gemessen vertikal zur Verbindungslinie zur nächsten Komponente.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords = {[21]{beamwidth}}]
\begin{pspicture}(4,4)
  \pnode(1.5,0.5){A}\pnode(3.5,0.5){B}\pnode(3.5,3.5){C} 
  \optbox[position=end](B)(A)
  \mirror[mirrortype=extended](A)(B)(C)
  \optplate[position=end](B)(C)
  \drawwidebeam[beamwidth=0.3]{-}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \psnumitem[0]{beamdiv}
% \ifENGLISH The total beam divergence at the starting position, given in
% degree. Positive values give an expanding beam, negative values a contracting
% beam.
% \fi
% \ifGERMAN Die Strahldivergenz an der Startposition, angegeben in
% Grad. Positive Werte ergebenen einen expandierenden Strahl, negative einen
% kontrahierenden.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords = {[21]{beamdiv}}, linerange={1-8,11-11}]
\begin{pspicture}(3,2)
  \pnode(0,1){A}\pnode(3,1){B}
  \psset{plateheight=2}
  \optplate[position=start](A)(B)
  \optplate[position=end](A)(B)
  \addtopsstyle{Beam}{beamwidth=0.2}
  \drawwidebeam[beampos=0.4, beamdiv=5]{-}
  \drawwidebeam[beampos=-0.4, beamdiv=-5, linecolor=red]{-}
  \rput[b](1.5,0){\footnotesize\ttfamily beamdiv < 0}
  \rput[t](1.5,2){\footnotesize\ttfamily beamdiv > 0}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
%
% \ifENGLISH\subsection{Beam appearance}\fi
% \ifGERMAN\subsection{Strahlaussehen}\fi
%
% \ifENGLISH
% The appearance of wide beams can be controlled like that of single beams with
% the optional argument or the \Lstyle{Beam} style (see
% \prettyref{sec:beamappearance-single}).
%
% Wide beams have two marginal rays, which are drawn according to the line
% settings, and may be filled.
% \fi
% \ifGERMAN Das Aussehen aufgeweiteter Strahlen kann genauso wie bei einfachen
% Strahlen über \Lstyle{Beam} oder das optionale Argument vorgegeben werden
% (siehe \prettyref{sec:beamappearance-single}).
%
% Breite Strahlen bestehen aus zwei Randstrahlen, die gemäß der
% Linieneinstellungen gezeichnet werden, und können zusätzlich gefüllt werden.
% \fi
%
% \begin{enumerate}
% \item 
%   \ifENGLISH Only marginal rays.\fi
%   \ifGERMAN Nur die Randstrahlen.\fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
  \pnode(0,0.5){A}\pnode(1,0.5){B}\pnode(2.8,2){C}
  \mirror[mirrorwidth=1.5](A)(B)(C)
  \drawwidebeam[beamwidth=0.4](A){}(C)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \item 
%   \ifENGLISH Marginal rays, and with fill style.\fi
%   \ifGERMAN Randstrahlen, und Füllstil.\fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]fillstyle, linestyle}]
\begin{pspicture}(3,2)
  \pnode(0,0.5){A}\pnode(1,0.5){B}\pnode(2.8,2){C}
  \mirror[mirrorwidth=1.5](A)(B)(C)
  \addtopsstyle{Beam}{fillstyle=solid, fillcolor=red!50!white, linecolor=red}
  \drawwidebeam[beamwidth=0.4](A){}(C)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \item
%   \ifENGLISH Only with fill style.\fi
%   \ifGERMAN Nur Füllstil.\fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]fillstyle, linestyle}]
\begin{pspicture}(3,2)
  \pnode(0,0.5){A}\pnode(1,0.5){B}\pnode(2.8,2){C}
  \mirror[mirrorwidth=1.5](A)(B)(C)
  \addtopsstyle{Beam}{fillstyle=solid, fillcolor=red, opacity=0.3, linestyle=none}
  \drawwidebeam[beamwidth=0.4](A){}(C)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{enumerate}
%
% \ifGERMAN\section{Fehlerbehandlung}\fi
% \ifENGLISH\section{Error handling}\fi
% \label{sec:error-handling}
%
% \ifGERMAN
% Da alle Strahlen direkt mit Postscript berechnet und gezeichnet werden, ist
% eine umfassende Fehlerbehandlung zur Zeit der Kompilation nicht möglich. Um
% jedoch trotzdem fehlerfreie Bilder zu bekommen, wird der Strahlengang
% abgebrochen, sobald eine Situation eintritt, die nicht unterstützt wird. Das kann
% eintreten, falls der Strahl eine Grenzfläche nicht trifft, oder
% Totalreflektion auftritt.
% \fi
% \ifENGLISH All beam are calculated and drawn directly in Postscript, so that a
% comprehensive error handling at compilation time is not possible. If a
% situation arises which is not supported by the drawing algorithm, the beam
% path is truncated at this point. This happens in the following cases:
% \fi
% \begin{enumerate}
% \item 
%   \ifENGLISH A beam misses an interface. The red beam in the following example
%   misses the last plane and is truncated at the last valid interface.
%   \fi
%   \ifGERMAN Ein Strahl trifft eine Grenzfläche nicht. Der rote Strahl in dem
%   folgenden Beispiel verpasst die letzte Grenzfläche und endet daher an der
%   vorhergehenden.
%   \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2.7)
  \pnode(0,1){A}\pnode(3,1){B}
  \optplate[position=start](A)(B)
  \lens[lens=4 4 2, abspos=0.5, n=2.5](A)(B)
  \optplate[position=end, plateheight=0.5](A)(B)
  \drawbeam{-}
  \drawbeam[beampos=0.2]{-}
  \drawbeam[beampos=0.4, linecolor=red]{-}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \item
%   \ifENGLISH When total internal reflection occurs at an interface which is
%   not set up for this. The red beam in the following example would be
%   reflected, but this is not supported and the beam is truncated at the
%   interface where the total internal reflection occurs.
%   \fi
%   \ifGERMAN Totale interne Reflektion tritt an einer Grenzfläche auf, die
%   nicht dafür vorgesehen ist. Der rote Strahl im folgenden Beispiel würde
%   reflektiert werden, aber das wird für diese Komponente nicht unterstützt und
%   der Strahl endet an der total reflektierenden Grenzfläche.
%   \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2.5)
  \pnode(0,2){A}\pnode(3,0){B}
  \optplane(A)
  \optprism[n=1.8](A)([Xnodesep=1.5]A)(B)
  \optplane(B)
  \drawbeam[beamangle=5]{-}
  \drawbeam[beamangle=-5, linecolor=red]{-}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{enumerate}
%
% \ifGERMAN Dasselbe gilt ebenfalls für aufgeweitete Strahlen (siehe
% \prettyref{sec:drawwidebeam}). Bei diesen wird der Strahlengang abgebrochen,
% falls einer der beiden Randstrahlen einen Fehler aufweist.
% \fi
% \ifENGLISH These conditions apply to wide beams (see \prettyref{sec:drawwidebeam}) as
% well, the beam path is interrupted as soon as one of the marginal rays has an
% error.
% \fi
%
% \begin{optionlist}
%   \boolitem[false]{pswarning} 
%   \ifENGLISH To simplify debugging, you can print a message to
%   standard output if a beam misses an interface or if total internal
%   reflection occured at some point.
%   \fi
%   \ifGERMAN Um eine Fehlersuche zu vereinfachen kann ein Hinweis ausgegeben
%   werden sobald ein Strahlengang vorzeitig beendet wird weil entweder eine
%   Grenzfläche verpasst wird, oder totale interne Reflektion auftritt.
%\fi
% \end{optionlist}
% 
% \ifGERMAN\section{Angepasste Strahlen}\fi
% \ifENGLISH\section{Custom beams}\fi
% \label{sec:custombeam}
%
% \ifGERMAN 
% Im Prinzip können alle Strahlengänge mit passender Wahl des Brechungsindex und
% der Komponentenparameter (z.B. der Linsenkrümmung) realisiert werden, was
% jedoch sehr aufwendig werden kann.  Um das zu vereinfachen, besteht die
% Möglichkeit die Endpunkte eines Strahls als Anfangspunkte für folgende
% Strahlen zu nutzen, so dass man abschnittsweise die Divergenz und die
% Ausbreitungsrichtung definieren kann.
% \fi
% \ifENGLISH
% With an appropriate choice of refractive index and component parameters
% (e.g. lens curvature) all kind of beam paths could be realised although it
% might be very cumbersome. To simplify this we provide the possibility to use
% the end points of one beam path as starting points for the next beam which
% allows piecewise definition of the beam divergence, angle, and direction.
% \fi
%
% \begin{optionlist}
%   \choitem[true]{savebeampoints}{true,false,\prm{int}}
%   \ifGERMAN Speichert die Endpunkte eines \nxLcs{draw*beam} Makros,
%   vorangegangene Punkte werden überschrieben. \Lcs{drawbeam} und
%   \Lcs{drawwidebeam} werden getrennt behandelt. Wird hier eine Zahl \prm{int}
%   $> 0$ angegeben, so können beliebig viele Endpunkte separat gespeichert
%   werden. In der Regel reicht an- und abschalten vollkommen aus.
%   \fi
%   \ifENGLISH Saves the end points of a \nxLcs{draw*beam} macro, previous
%   points are overwritten. \Lcs{drawbeam} and \Lcs{drawwidebeam} are treated
%   separately. If a number \prm{int} $> 0$ is given, you can save as many end
%   points as you like, but in most use cases enabling and disabling this option
%   is sufficient.
%   \fi
%
%   \choitem[false]{loadbeampoints}{true,false,\prm{int}}
%   \ifGERMAN Verwende die Endpunkte eines vorangegangenen Strahls als
%   Startpunkte. Wird keine Zahl \prm{int} angegeben, dann wird \opt{1}
%   verwendet.
%   \fi
%   \ifENGLISH Use the end points of a previous beam as starting points for the
%   next beam. If no number \prm{int} is specified, \opt{1} is used.
%   \fi
% \end{optionlist}
%
% \ifGERMAN Als Beispiel nehmen wir ein Teleskop, die Strahldivergenz am Eingang
% und am Ausgang ist Null. Anstatt die Linsenparameter und den Brechungsindex
% genau einzustellen, so dass die Ausgangsdivergenz Null ist, zeichnen wir
% einfach die drei Strahlenteile mit den gewünschten Divergenzen, und verwenden
% die Endpunkte des jeweils vorangegangenen Strahls als neue Ausgangspunkte. 
% \fi
% \ifENGLISH As example we consider a telescope which has zero divergence at the
% input and output. Usually we would need to tweak the refractive index and the
% lens parameters to get an output beam with no divergence. Instead, we draw the
% three beam parts separately using the end points of the previous beams as new
% starting points and specifying the divergence for each beam part
% explicitely.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{savebeampoints, loadbeampoints}}]
\begin{pspicture}(4,2) 
  \pnode(0,1){A}\pnode(4,1){B}
  \begin{optexp}
    \lens[lens=0.5 0.5 0.5, abspos=0.5](A)(B)
    \lens[lens=4 4 2, abspos=2](A)(B)
    \addtopsstyle{Beam}{%
      fillstyle=solid, fillcolor=green, opacity=0.3}
    \psset{loadbeampoints}
    \drawwidebeam[beamwidth=0.2, stopinside](A){1}
    \drawwidebeam[beamdiv=-60]{1}{2}
    \drawwidebeam{2}(B)
  \end{optexp}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN Als weiteres Beispiel betrachten wir die Beugung an einem Gittern in
% die nullte und erste Beugungsordnung. Zuerst wird der Strahl von dem Eingang
% bis zum Gitter gezeichnet, die Endpunkte dieses Strahls werden nun für die
% Strahlen in beide Beugungsordnungen verwendet.
% \fi
% \ifENGLISH The next example shows diffraction from a grating in the zeroth and
% first diffraction order. First we draw the beam to the grating, its end points
% are used for the beams into both diffraction orders.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{savebeampoints, loadbeampoints}},
  linerange={1-12,16-16}, caption={caption}, label={ex:loadbeampoints}]
\begin{pspicture}(3.5,3.5)
  \pnode(0,0.5){A}\pnode(2,0.5){B}\pnode(2,3){C}
  \nodexn{(C)-(1,0)}{C'}
  \nodexn{(C)(1,0)}{C''}
  \optgrating(A)(B)(C)
  \addtopsstyle{Beam}{%
    fillstyle=solid, fillcolor=green, opacity=0.3}
  \drawwidebeam[beamwidth=0.3](A){1}
  \psset{savebeampoints=false, loadbeampoints}
  \drawwidebeam{1}(C)
  \drawwidebeam{1}(C')
  \drawwidebeam{1}(C'')
  \rput[b]([offset=0.2]C){0th}
  \rput[b]([offset=0.2]C'){1st}
  \rput[b]([offset=0.2]C''){-1st}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \begin{optionlist}
%   \boolitem[true]{savebeam}
%   \ifGERMAN Speichert die Endzustände, d.h. Endpunkte und Ausgangsvektoren,
%   eines \nxLcs{draw*beam} Makros, vorangegangene Werte werden
%   überschrieben. \Lcs{drawbeam} und \Lcs{drawwidebeam} werden getrennt
%   behandelt. Wird hier eine Zahl \prm{int} $> 0$ angegeben, so können beliebig
%   viele Strahlen separat gespeichert werden. In der Regel reicht an- und
%   abschalten vollkommen aus.
%   \fi
%   \ifENGLISH Saves the end conditions, i.e. end points and output vectors, of
%   each \nxLcs{draw*beam} macro, previous values are
%   overwritten. \Lcs{drawbeam} and \Lcs{drawwidebeam} are treated
%   separately. If a number \prm{int} $> 0$ is given, you can save as many end
%   points as you like, but in most use cases enabling and disabling this option
%   is sufficient.
%   \fi
%
%   \boolitem[false]{loadbeam}
%   \ifGERMAN Verwende den Endzustand (Punkte und Richtung) eines
%   vorangegangenen Strahls als Anfangszustand. Der Parameter
%   \Lkeyword{beamangle} kann verwendet werden um die Richtung relativ zu der
%   geladenen zu verändern (siehe folgendes Beispiel).
%   \fi
%   \ifENGLISH Use the end condition (points and vectors) of a previous beam as
%   starting conditions for the next beam. The parameter \Lkeyword{beamangle}
%   can be used to change the direction relative to the loaded one (see
%   following example).
%   \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{savebeam, loadbeam}},
  linerange={1-10,14-14}, caption={caption}, label={ex:loadbeam}]
\begin{pspicture}(3.5,3.5)
  \pnode(0,0.5){A}\pnode(2,0.5){B}\pnode(2,3){C}
  \optgrating(A)(B)(C)
  \addtopsstyle{Beam}{%
    fillstyle=solid, fillcolor=green, opacity=0.3}
  \drawwidebeam[savebeam, beamwidth=0.3](A){1}
  \psset{savebeam=false, loadbeam}
  \drawwidebeam[beamangle=-20]{1}(C)
  \drawwidebeam{1}(C)
  \drawwidebeam[beamangle=20]{1}(C)
  \rput[b]([offset=0.2]C){0th}
  \rput[b]([Xnodesep=-0.9, offset=0.2]C){1st}
  \rput[b]([Xnodesep=0.9,offset=0.2]C){-1st}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN Beachten Sie, dass \Lkeyword{loadbeam} und
% \Lkeyword{savebeam} nicht immer funktionieren, wenn der Strahlengang an
% einem halbdurchlässigen Spiegel oder einem Strahlteiler endet. In
% diesen Fällen wird nur der transmittierte Strahlvektor gespeichert,
% soll der Strahlengang über den reflektierenden Weg fortgesetzt werden,
% so ist das nicht möglich. 
%
% In den beiden folgenden Beispielen wird demnach der rote Strahl, der
% von der Komponente zum Knoten \prm{B} fortgesetzt werden soll, nicht
% gezeichnet. 
% \fi
% \ifENGLISH Please note, that \Lkeyword{loadbeam} and
% \Lkeyword{savebeam} do not always work, if the beam path ends inside a
% semitransparent mirror or a beamsplitter. In these cases only the
% transmitted ray vector is saved and continuing the beam via the
% reflective path is not possible.
%
% Accordingly, in the following examples the red beam is not drawn,
% which should continue the green beam from the component to node
% \prm{B}.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-6,9-9}]
\begin{pspicture}(3,1.5)
  \pnode(0,0.5){A}\pnode(1.5,1.5){B}\pnode(3,0.5){C}
  \beamsplitter(A)(1.5,0.5)(B)
  \drawbeam[beaminsidelast, savebeam](A){}
  \drawbeam[linecolor=red, beaminsidefirst, loadbeam]{}(B)
  \drawbeam[linecolor=blue, beaminsidefirst, loadbeam]{}(C)
  \psdot(B)\uput[-30](B){B}
  \psdot(C)\uput[-120](C){C}
\end{pspicture}
\end{LTXexample}

\begin{LTXexample}[linerange={1-6,9-9}]
\begin{pspicture}(3,1.5)
  \pnode(0,0.5){A}\pnode(1.5,1.5){B}\pnode(3,0.5){C}
  \mirror[mirrortype=semitrans](A)(1.5,0.5)(B)
  \drawbeam[beaminsidelast, savebeam](A){}
  \drawbeam[linecolor=red, beaminsidefirst, loadbeam]{}(B)
  \drawbeam[linecolor=blue, beaminsidefirst, loadbeam]{}(C)
  \psdot(B)\uput[-30](B){B}
  \psdot(C)\uput[-120](C){C}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
%
% 
%
% \begin{optionlist}
%   \boolitem[false]{startinside}
%   \ifENGLISH
%   The parameter \Lkeyword{beaminsidefirst} controls if the internal beams are
%   drawn inside the first component. However, for custom beams it can also be
%   necessary to trace the internal beam of the first component without drawing
%   it, e.g. if the previous beam ended at the first interface.
%
%   In the following example the red beam is the wrong continuation of the
%   incoming green beam because it assumes that the loaded beam conditions refer
%   to the output interface. But the previous beam stopped at the input
%   interface, so one needs to set \Lkeyword{startinside} in order to continue
%   the beam properly (see blue beam). The dashed line helps to understand the
%   correct beam path through the lens.
%   \fi
%   \ifGERMAN Mit dem Parameter \Lkeyword{beaminsidefirst} kann eingestellt
%   werden, ob der interne Strahlengang in der erste Komponente gezeichnet
%   wird. Für angepasste Strahlengänge kann es aber notwendig sein dem internen
%   Strahlengang in der ersten Komponente zu folgen ohne diesen zu zeichnen,
%   z.B. wenn der vorangegangene Strahl an der ersten Grenzfläche schon endet.
%   
%   Im folgenden Beispiel wird der einfallende grüne Strahl falsch durch den
%   roten Strahl fortgesetzt, da der grüne an der linken Grenzfläche endet, der
%   rote aber fälschlicherweise annimmt, dass der Endzustand sich auf die rechte
%   Grenzfläche bezieht. Dem blauen Strahl wird nun mit \Lkeyword{startinside}
%   mitgeteilt, dass der Endzustand sich auf die linke Grenzfläche bezieht.
%   \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords = {[21]{startinside}}]
\begin{pspicture*}(0,2)(3.05,6)
  \optplane(0,2)
  \lens[lens=8 8 8, abspos=0.6, n=1.8](0.5,2)(3,2)
  \optplate[position=1, plateheight=6](0.5,2)(3,2)
  \psset{savebeam=false}
  \drawbeam[beampos=3, linestyle=dashed]{-}
  \drawbeam[beampos=3, savebeam]{1-2}
  \drawbeam[loadbeam, linecolor=red]{2-3}
  \drawbeam[loadbeam, startinside, linecolor=blue]{2-3}
\end{pspicture*}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%   
%   \boolitem[false]{stopinside}
%   \ifENGLISH This option is equivalent to \Lkeyword{startinside} but refers
%   to the last component.
%   \fi
%   \ifGERMAN Äquivalent zu \Lkeyword{startinside}, bezieht sich aber auf die
%   letzte Komponenten.
%   \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords = {[21]{stopinside}}]
\begin{pspicture*}(0,2)(3.05,6)
  \optplane(0,2)
  \lens[lens=8 8 8, abspos=0.6, n=1.8](0.5,2)(3,2)
  \optplate[position=1, plateheight=6](0.5,2)(3,2)
  \psset{savebeam=false}
  \drawbeam[beampos=3, linestyle=dashed]{-}
  \drawbeam[beampos=3, savebeam, stopinside]{1-2}
  \drawbeam[loadbeam, linecolor=blue]{2-3}
\end{pspicture*}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
%
%
% \ifGERMAN\section{Faserverbindungen}\fi
% \ifENGLISH\section{Drawing fibers}\fi
% \label{sec:drawfiber}
%
% \ifENGLISH
% All available components can be connected with fiber connections, the
% fiber components are connected automatically.
% \fi
% \ifGERMAN
% Alle Komponenten können mit Fasern verbunden werden, die Faserkomponenten
% werden automatisch verbunden.
% \fi
%
% \begin{ltxsyntax}
%   \xLcs{drawfiber}\cmditem{drawfiber}[options]{obj$_1$}{obj$_2$}\ldots
% \end{ltxsyntax}
% 
% \ifENGLISH
% The \Lcs{drawfiber} command takes ID, \Lkeyword{compname}, or nodes as
% \prm{obj$_N$} arguments (see \prettyref{sec:accessobj}), but ID ranges like
% with \Lcs{drawbeam} are not possible. If you specify more than two arguments,
% you get connections $1\rightarrow 2$, $2\rightarrow 3$, and so on.
%
% The automatic fiber connections are drawn internally with \Lcs{drawfiber}
% commands from each reference node to the component.
% \fi
% \ifGERMAN
% Das \Lcs{drawfiber} Makro kann ID, \Lkeyword{compname} oder Knoten als
% \prm{obj$_N$} Argumente verarbeiten (siehe \prettyref{sec:accessobj}), aber
% ID-Intervalle wie bei \Lcs*{draw*beam} sind nicht möglich. Werden mehr als
% zwei Argumente mitgegeben, werden die Verbindungen $1\rightarrow 2$,
% $2\rightarrow 3$, usw. gezeichnet.
%
% Die automatischen Faserverbindungen werden intern als \Lcs{drawfiber} von den
% Referenzknoten zur Komponente gezeichnet.
% \fi
%
% \ifENGLISH\subsection{Fiber angles}\fi
% \ifGERMAN\subsection{Faserwinkel}\fi
% \label{sec:drawfiber-angles}
% 
% \ifENGLISH
% The fibers are usually drawn as \Lcs*{nccurve} connections, the angles at both
% curve ends are automatically determined by the component orientation and
% depend on whether you connect a component with a component, or a component
% with a node.
% \fi
% \ifGERMAN
% Üblicherweise werden Fasern als \Lcs*{nccurve}-Verbindungen gezeichnet, die
% Winkel an beiden Kurvenenden werden automatisch anhand der
% Komponentenausrichtung bestimmt und hängen davon ab, ob eine Komponente mit
% einer anderen Komponente oder einem Knoten verbunden wird.
% \fi
% 
% \ifENGLISH\minisec{Component with node}\fi
% \ifGERMAN\minisec{Komponente mit Knoten}\fi
%
% \ifENGLISH
% A connection of a component with a node is what is used for automatic
% connections (see \prettyref{sec:drawfiber-auto}). Consider the following
% example for clarification of the curve alignment:
% \fi
% \ifGERMAN
% Eine Verbindung zwischen einer Komponente und einem Knoten ist das, was bei
% automatischen Verbindungen verwendet wird (siehe
% \prettyref{sec:drawfiber-auto}). Folgendes Beispiel erläutert die Ausrichtung
% der Kurve:
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-3,10-11}]
\begin{pspicture}(-1,-0.7)(7,2.7)
  \pnode(0,1){A}\pnode(6,1){B}
  \optbox[angle=30](A)(B)
  \psdot(\oenodeRefA{})\uput[180](\oenodeRefA{}){RefA}%
  \psdot(\oenodeRefB{})\uput[0](\oenodeRefB{}){RefB}%
  \psdot(\oenodeTrefA{})\uput[180](\oenodeTrefA{}){TrefA}%
  \psdot(\oenodeTrefB{})\uput[0](\oenodeTrefB{}){TrefB}%
  \psline[style=Refline, linestyle=dashed](\oenodeTrefA{})(\oenodeTrefB{})
  \psline[style=Refline, linestyle=dashed](\oenodeRefA{})(\oenodeRefB{})
  \drawfiber(A){}(B)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \ifENGLISH
% The angle at the component itself agrees with the transformed reference line.
% The angle at the node corresponds to the angle of the original reference line
% of the component which it gets connected to. The fiber is always directed to
% the component node.
%
% Considering the following example, this means that the start angles of the red
% fibers are rotated by 180° with respect to the green fibers. The angles at the
% component do not change.
% \fi
% \ifGERMAN
% Der Winkel an der Komponente entspricht dem der transformierten
% Referenzlinie. Der Winkel an dem Knoten entspricht dem der ursprünglichen
% Referenzlinie der Komponente zu der die Verbindung geht. Die Faser ist in
% Richtung des entsprechenden Komponentenknotens orientiert. 
%
% Das führt dazu, dass im folgenden Beispiel die Anfangswinkel der roten Fasern
% um 180° gegenüber den grünen Fasern gedreht sind, die Winkel an der Komponente
% bleiben unverändert.
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-1,4-4,7-14}]
\begin{pspicture}(-2,-1.6)(2,2)
  \psset[optexp]{optboxsize=1.6 0.8}
  \addtopsstyle{Fiber}{ArrowInside=->, arrowscale=1.5}
  \optbox[position=end](0,1)(0,0)
  \psarc[fillstyle=solid,fillcolor=gray!20, linestyle=none](0,0){2}{0}{180}
  \psline[linestyle=dashed]([Xnodesep=-2]\oenodeIn{})([Xnodesep=2]\oenodeIn{})
  \addtopsstyle{Fiber}{linecolor=green!90!black}
  \multido{\i=10+40}{5}{%
    \drawfiber(2;\i){}
  }
  \addtopsstyle{Fiber}{linecolor=red!90!black}
  \drawfiber(2;-20){}
  \drawfiber(2;200){}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifENGLISH\minisec{Component with component}\fi
% \ifGERMAN\minisec{Komponente mit Komponente}\fi
% 
% \ifENGLISH
% This variant is very helpful to achieve smoother connections between
% components which are not aligned on the same reference line but are arranged
% maybe in a loop or similar, see \prettyref{ex:nalm} and
% \prettyref{ex:recirc-loop}.
%
% In this case, the curve angles are determined by the component which the
% respective curve end is connected to. The fibers are always directed away from
% the component center.
% \fi
% \ifGERMAN
% Diese Variante ist sehr nützlich um glattere Verbindungen zwischen Komponenten
% zu erreichen, die nicht auf derselben Referenzlinie positioniert sind, sondern
% z.B. in einer Schleife angeordnet werden, siehe \prettyref{ex:nalm} und
% \prettyref{ex:recirc-loop}.
%
% In diesem Fall werden die Kurvenwinkel von der Komponente bestimmt, mit der
% das jeweilige Ende verbunden ist. Die Fasern zeigen immer von der
% Komponentenmitte weg.
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-5,10-11}]
\begin{pspicture}(0,-0.8)(7,0.8)
  \pnode(0,0){A}\pnode(3,0){B}
  \pnode(4,0){C}\pnode(7,0){D}
  \optbox[angle=30](A)(B)
  \optbox[angle=-30](C)(D)
  \psline[style=Refline, linestyle=dashed](\oenodeTrefA{1})(\oenodeTrefB{1})
  \psline[style=Refline, linestyle=dashed](\oenodeTrefA{2})(\oenodeTrefB{2})
  \psline[style=Refline, linestyle=dashed](\oenodeRefA{1})(\oenodeRefB{2})
  \psdot(\oenodeRefA{1})\psdot(\oenodeRefB{2})
  \drawfiber(A){1}{2}(D)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifENGLISH These automatically calculated start and stop angles can be changed
% in a variety of ways, the available parameters are listed in the following.
% \fi
% \ifGERMAN
% Diese automatisch berechneten Winkel können vielfältig manipuliert werden, die
% möglichen Parameter sind im Folgenden aufgelistet.
% \fi
%
% \begin{optionlist}
%   \choitem[relative]{fiberalign}{rel,relative,center,abs,absolute}
%   \ifENGLISH Set the reference for the fiber angles.
%   \fi
%   \ifGERMAN
%   Wählt die Referenz für die Faserwinkel.
%   \fi
%   \begin{valuelist}
%   \item[relative] 
%     \ifENGLISH The fiber angles are relative to the component. When
%     connecting a node to a component, the angle at the node is that of the
%     component reference line. The angle at the component agrees with that of
%     its transformed reference line.
%     \fi
%     \ifGERMAN
%     Die Faserwinkel sind relativ zur Komponente. Wird ein Knoten mit der
%     Komponente verbunden, so entspricht der Winkel am Knoten dem der
%     Referenzlinie der Komponente. Der Winkel an der Komponente entspricht dem
%     der transformierten Referenzlinie.
%     \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-5,10-11}]
\begin{pspicture}(1,-1.7)(7,1.7)
  \pnode(0,0){A}\pnode(3,0){B}
  \pnode(4,0){C}\pnode(7,0){D}
  \optbox[angle=30](A)(B)
  \optbox[angle=-30](C)(D)
  \psline[style=Refline, linestyle=dashed](\oenodeTrefA{1})(\oenodeTrefB{1})
  \psline[style=Refline, linestyle=dashed](\oenodeTrefA{2})(\oenodeTrefB{2})
  \psline[style=Refline, linestyle=dashed](\oenodeRefA{1})(\oenodeRefB{2})
  \psdot(\oenodeRefA{1})\psdot(\oenodeRefB{2})
  \drawfiber(A){1}{2}(D)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \item[center] 
%   \ifENGLISH The fiber angles both at the node and the component are relative
%   to the connection between the involved interface node and the center node of
%   the component. In most cases this is equivalent to \opt{relative}, but
%   necessary e.g. for \Lcs{optcirculator}. In the example, the green fiber
%   shows the correct alignment, while the red one is with \opt{relative}
%   alignment.
%   \fi
%   \ifGERMAN
%   Die Winkel sowohl am Knoten als auch an der Komponente sind relativ zu der
%   Verbindung zwischen dem betroffenen Komponentenknoten und der
%   Komponentenmitte. Meistens ist das äquivalent zu \opt{relative}, wird aber
%   z.B. für \Lcs{optcirculator} benötigt. In dem Beispiel hat die grüne Faser
%   die korrekte Ausrichtung, während die rote \opt{relative} ausgerichtet wird.
%   \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]fiberalign}]
\begin{pspicture}(1,0)(3,2)
  \addtopsstyle{Fiber}{arrowscale=1.3, arrows=->, arrowinset=0}
  \optcirculator[fiber=t](0,0.5)(3,2)(1.5,0)
  \drawfiber[linecolor=red]{}(1.5,0)
  \drawfiber[fiberalign=center, linecolor=green]{}(1.5,0)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \item[absolute] 
%   \ifENGLISH The fiber angles are absolute, no automatic values are added.
%   \fi
%   \ifGERMAN
%   Die Faserwinkel werden als absolute Werte angegeben, die automatischen
%   Winkel werden nicht berücksichtigt.
%   \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]fiberalign}, linerange={1-3,7-8}]
\begin{pspicture}(1,-1)(4.5,1)
  \pnode(0,0){A}\pnode(4,0){B}
  \optbox[angle=30](A)(B)
  \psline[style=Refline, linestyle=dashed](\oenodeTrefA{})(\oenodeTrefB{})
  \psline[style=Refline, linestyle=dashed](\oenodeRefA{})(\oenodeRefB{})
  \psdot(\oenodeRefA{})\psdot(\oenodeRefB{})
  \drawfiber[fiberalign=abs, ncurv=1.5](A){}(B)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%   \end{valuelist}
%
%   \numitem[0]{fiberangleA}
%   \ifENGLISH An additive value for the starting angle, the total angle depends
%   on \Lkeyword{fiberalign}. If this parameter is set to \opt{absolute}, then
%   \Lkeyword{fiberangleA} is the total angle, otherwise its value is added to
%   the calculated angle.
%   \fi
%   \ifGERMAN
%   Ein additiver Wert für den Anfangswinkel, der gesamte Winkel hängt von
%   \Lkeyword{fiberalign} ab. Ist dieser auf \opt{absolute} eingestellt, so ist
%   \Lkeyword{fiberangleA} der absolute Winkel, andernfalls wird der Wert zu dem
%   automatisch berechneten Winkel hinzuaddiert.
%   \fi
%
%   \numitem[0]{fiberangleB}
%   \ifENGLISH Like \Lkeyword{fiberangleA}, but for the end angle.\fi
%   \ifGERMAN Wie \Lkeyword{fiberangleB}, aber für den Endwinkel.\fi
% 
%   \choitem[auto]{startnode}{auto, N, 1, 2, \ldots}
%   \ifGERMAN Für die Verbindungen mit \Lcs{drawfiber} werden die Knoten
%   genommen, die sich am nächsten sind. Das passt häufig, aber nicht
%   immer. Hiermit kann der Startknoten explizit gewählt werden.
%   \fi
%   \ifENGLISH The connections with \Lcs{drawfiber} are drawn between the
%   two nodes which are nearest to each other. This fits most of the time, but not
%   always. With this option you can choose the start node explicitely.
%   \fi
%
%   \choitem[auto]{stopnode}{auto, N, 1, 2, \ldots}
%   \ifGERMAN Genau wie \Lkeyword{startnode}, aber für den Stopknoten.\fi
%   \ifENGLISH Like \Lkeyword{startnode}, but for the stop node.\fi
% \end{optionlist}
%
% \ifENGLISH
% The following examples show some use cases for \Lkeyword{startnode} and
% \Lkeyword{stopnode}.
% \fi
% \ifGERMAN
% Die folgenden Beispiele zeigen Anwendungsmöglichkeiten für
% \Lkeyword{startnode} und \Lkeyword{stopnode}.
% \fi
%
% \begin{enumerate}
% \item 
%   \ifENGLISH This example shows a situation, where choosing the nearest nodes
%   is correct.
%   \fi
%   \ifGERMAN In diesem Fall ist der nächstgelegene Knoten auch der richtige.
%   \fi
% 
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
  \pnode(-0.5,1){A}\pnode(1.5,1){B}\pnode(3.5,1){C}
  \psset{label=0, optboxwidth=1}
  \optbox(A)(B){Box1}\optbox(B)(C){Box2}
  \drawfiber{1}{2}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \item 
%   \ifENGLISH In this case, the nearest connection is not well defined because
%   two connections have the same length.
%   \fi
%   \ifGERMAN
%   Hier ist der kürzeste Abstand nicht eindeutig definiert, da es zwei
%   Verbindungen mit der gleichen Länge gibt.
%   \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
  \pnode(0,0.5){A}\pnode(3,0.5){B}
  \pnode([offset=1]B){C}\pnode(A|C){D}
  \psset{label=0}
  \optbox(A)(B){Box1}\optbox(C)(D){Box2}
  \drawfiber{1}{2}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \item 
%   \ifENGLISH To select the desired connection it is often enough to set either
%   \Lkeyword{startnode} or \Lkeyword{stopnode}. With this you fix one node, the
%   other is the one nearest to it. In rare cases it might be necessary to fix
%   both nodes.
%   \fi
%   \ifGERMAN
%   Um die gewünschte Verbindung zu wählen ist es meistens ausreichend entweder
%   \Lkeyword{startnode} oder \Lkeyword{stopnode} zu setzen. Ist ein Knoten fest
%   vorgegeben, wird der anderen wieder als der mit dem kürzesten Abstand
%   gewählt. Nur in Ausnahmefällen sollte es notwendig sein beide Knoten
%   explizit anzugegeben.
%   \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]startnode}]
\begin{pspicture}(2,2)
  \pnode(0,0.5){A}\pnode(2,0.5){B}
  \pnode([offset=1]B){C}\pnode(A|C){D}
  \psset{label=0}
  \optbox(A)(B){Box1}\optbox(C)(D){Box2}
  \drawfiber[startnode=1]{1}{2}
  \drawfiber[startnode=N, linecolor=black]{1}{2}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \item 
%   \ifENGLISH Another example where you need to specify the
%   \Lkeyword{startnode}.
%   \fi
%   \ifGERMAN Ein weiteres Beispiel, bei dem \Lkeyword{startnode} vorgegeben
%   werden muss.
%   \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]startnode}, caption={caption}, label={ex:nalm}]
\begin{pspicture}(2.1,3)
  \pnode(0,0){A}\pnode(2,0){B}
  \pnode(0.3,3){C}\pnode(1.7,3){D}
  \psset{fiber=none}
  \optcoupler[fiber=l,
                addtoFiberIn1={angleA=0, ArrowInside=->},
                addtoFiberIn2={angleA=180, arrows=<-},
                abspos=0.5, compname=Cpl](A)(B)(C)(D)
  \optfiber[compname=Hnlf, abspos=1](C)(C|A)
  \optamp[abspos=2, compname=Amp](D|B)(D)
  \drawfiber{Cpl}{Hnlf}
  \drawfiber[startnode=1, ncurv=1.2]{Hnlf}{Amp}
  \drawfiber{Cpl}{Amp}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{enumerate}
%
% \ifENGLISH\subsection{Fiber appearance}\fi
% \ifGERMAN\subsection{Faseraussehen}\fi
% \label{sec:fiberappearance}
%
% \begin{optionlist}
%   \styleitem{Fiber}
%   \ifENGLISH
%   The appearance of fibers is controlled with this style. The optional
%   argument of \Lcs{drawfiber} can be used as well, these options can overwrite
%   settings from the \Lstyle{Fiber} style.
%   \fi
%   \ifGERMAN
%   Das Aussehen der Fasern wird durch diesen Stil vorgegeben. Das optionale
%   Argument von \Lcs{drawfiber} kann ebenfalls verwendet werden, die
%   entsprechenden Parameter können die Einstellungen von \Lstyle{Fiber}
%   überschreiben.
%   \fi
%
%   \valitem{addtoFiber}{list}
%     \addtostylemsg{Fiber}
%
%   \valitem{newFiber}{list}
%     \newstylemsg{Fiber}
% 
%   \valitem[curve]{fiberstyle}{string}
%   \ifGERMAN
%   Die Fasern werden in der Regel als \Lcs*{nccurve} gezeichnet, aber eine
%   beliebige andere Knotenverbindung \nxLcs{nc}\prm{string} des
%   \LPack{pst-node} Paketes kann ausgewählt werden, lesen Sie die entsprechende
%   Dokumentation\fnurl{http://mirror.ctan.org/help/Catalogue/entries/pst-node.html}
%   für mögliche Werte. In den folgenden Beispielen werden
%   Anwendungsmöglichkeiten gezeigt, eine weitere ist in
%   \prettyref{ex:transmission-loop} zu sehen.
%   \fi
%   \ifENGLISH 
%   The fibers are usually drawn as \Lcs*{nccurve}, but any type of node
%   connection \nxLcs{nc}\prm{string} from \LPack{pst-node} can be selected with
%   this parameter, see the \LPack{pst-node}
%   documentation\fnurl{http://mirror.ctan.org/help/Catalogue/entries/pst-node.html}
%   for possible values. The following examples show possible use cases,
%   \prettyref{ex:transmission-loop} contains another typical use case.
%   \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]fiberstyle}]
\begin{pspicture}(3,3)
  \pnode(1, 0.5){A}\pnode(2.5,0.5){B}\pnode(2.5,2){C}
  \psset{optboxsize=1 0.6, innerlabel}
  \optbox[position=start](A)(B){start}
  \optbox[position=end](B)(C){stop}
  \drawfiber[fiberstyle=diag, linearc=0.5]{1}{2}
\end{pspicture}
\end{LTXexample}

\begin{LTXexample}[morekeywords={[21]fiberstyle}, label={ex:recirc-loop}, caption={caption}]
\begin{pspicture}(4,2.5)
  \pnode(1,2.5){In}\pnode(3,2.5){Out}
  \pnode(0,2){A}\pnode(4,2){B}\pnode(4,0){C}\pnode(0,0){D}
  \optcoupler[fiber=t, addtoFiber={ArrowInside=->}, coupleralign=b](In)(A)(Out)(B)
  \psset{fiber=none}
  \optamp[position=0.35](C)(D)
  \optfiber[position=0.35](D)(C)
  \drawfiber{2}{3}
  \addtopsstyle{Fiber}{fiberstyle=bar, linearc=0.5, armA=1.5}
  \drawfiber[stopnode=1]{1}{2}
  \drawfiber[stopnode=1]{1}{3}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
% 
%
% \ifENGLISH\subsection{Automatic fiber connections}\fi
% \ifGERMAN\subsection{Automatische Faserverbindungen}\fi
% \label{sec:drawfiber-auto}
%
% \ifENGLISH
% All fiber components described in \prettyref{chap:fibercomp} are connected
% automatically to their reference nodes with \Lcs{drawfiber}, their behaviour
% is descibed in \prettyref{sec:drawfiber-angles}. The fiber connections can be
% controlled in a number of ways, without need to explicitely use
% \Lcs{drawfiber}. The style of each fiber connection can be configure
% independently, see \prettyref{sec:drawfiber-auto-styles}.
% \fi
% \ifGERMAN
% Alle Faserkomponenten, die in \prettyref{chap:fibercomp} beschrieben werden,
% werden automatisch mit \Lcs{drawfiber} mit ihren Referenzknoten verbunden, das
% Verhalten ist in \prettyref{sec:drawfiber-angles} beschrieben. Die
% automatischen Faserverbindungen können umfangreich kontrolliert werden, ohne
% explizit \Lcs{drawfiber} zu benutzen. Das Aussehen jeder Verbindung kann
% ebenfalls separat konfiguriert werden, siehe
% \prettyref{sec:drawfiber-auto-styles}.
% \fi
%
% \begin{optionlist}
%   \choitem[all]{fiber}{[*+]none,all,i,o,\prm{refpoint}} 
%   \ifENGLISH This parameter selects which fiber connections are drawn.  The
%   value of this parameter can affect either only the fiber components
%   (if the value is prefixed with \opt{*}), only free-ray components (prefixed
%   with \opt{+}), or all components otherwise. Typical free-ray components
%   which are often used with fibers as well are \Lcs{optbox} and \Lcs{optdetector}.
%
%   You can select to connect \opt{all} nodes, \opt{none}, or select distinct
%   connections to draw. Value \opt{i} (\opt{l} is equivalent) draws all input
%   fibers, \opt{o} (\opt{r} is equivalent) draws all output fibers. These
%   values are exclusive, that means \opt{io} does not select all fibers, but
%   none.
%
%   Components which have more than one input or output fiber
%   (\hyperref[sec:coupler]{couplers} and \Lcs{optcirculator}) allow also
%   values \opt{t} and \opt{b}, possibly in combination with \opt{i}, \opt{o},
%   \opt{r}, or \opt{l}.
%
%   See the following examples for some variants.
%   \fi
%   \ifGERMAN
%   Dieser Parameter gibt an, welche Faserverbindungen gezeichnet werden. Der
%   Parameter kann nur die Faserkomponenten betreffen (falls ein \opt{*}
%   vorangestellt ist), nur die Freistrahlkomponenten (\opt{+} wird
%   vorangestellt), oder alle Komponenten. Typische Freistrahlkomponenten, die
%   häufig als Faserkomponenten verwendet werden, sind \Lcs{optbox} und
%   \Lcs{optdetector}.
%
%   Es können alle Verbindungen gezeichnet werden (\opt{all}), keine
%   (\opt{none}), oder es können bestimmte ausgewählt werden. Die Werte \opt{i}
%   (\opt{l} ist äquivalent) zeichnet nur die Eingangsfasern, \opt{o}
%   (bzw. \opt{r}) alle ausgehenden Fasern. Diese Angaben sind ausschließend,
%   d.h. mit \opt{io} werden gar keine Verbindungen gezeichnet.
%
%   Komponenten, die über mehr als einen Eingang oder Ausgang verfügen
%   (\hyperref[sec:coupler]{Koppler} und \Lcs{optcirculator}) erlauben
%   weitergehende Auswahl mit \opt{t} und \opt{b}, möglicherweise in Verbindung
%   mit \opt{i}, \opt{o}, \opt{l} und \opt{r}.
% 
%   Die folgenden Beispiele zeigen einige Möglichkeiten.
%   \fi
% \end{optionlist}
%
% \begin{enumerate}
% \item 
%   \ifENGLISH Enable all fiber connections for all components.\fi
%   \ifGERMAN Zeichne alle Fasern für alle Komponenten.\fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{fiber}}]
\begin{pspicture}(3,2)
  \psset{fiber}
  \optbox(0,1.5)(3,1.5)
  \optmzm(0,0.5)(3,0.5)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \item 
%   \ifENGLISH Draw only the input fiber of a fiber component (\Lcs{optmzm}),
%   the free-ray component (\Lcs{optbox}) is not affected.
%   \fi
%   \ifGERMAN Nur die Eingangsverbindung einer Faserkomponente (\Lcs{optmzm})
%   wird gezeichnet, die Freistrahlkomponente (\Lcs{optbox}) bleibt
%   unbeeinflusst.
%   \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{fiber}}]
\begin{pspicture}(3,2)
  \psset{fiber=*i}
  \optbox(0,1.5)(3,1.5)
  \optmzm(0,0.5)(3,0.5)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \item 
%   \ifENGLISH Draw only the output fiber of a free-ray component
%   (\Lcs{optbox}), but all connections of the fiber component (\Lcs{optmzm}).
%   \fi
%   \ifGERMAN Von der Freistahlkomponente wird nur die Ausgangsverbindung
%   gezeichnet, die Faserkomponente erhält jedoch alle Verbindungen.
%   \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{fiber}}]
\begin{pspicture}(3,2)
  \psset{fiber=+o}
  \optbox(0,1.5)(3,1.5)
  \optmzm(0,0.5)(3,0.5)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \item 
%   \ifENGLISH The values \opt{t} and \opt{b} affect only components which have
%   more than two fibers, i.e \Lcs{optcirculator} and the couplers
%   (\prettyref{sec:coupler}).
%   \fi
%   \ifGERMAN
%   Die Werte \opt{t} und \opt{b} betreffen nur die Komponenten mit mehr als
%   zwei Verbindungen, also \Lcs{optcirculator} und die Koppler
%   (\prettyref{sec:coupler}).
%   \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{fiber}}]
\begin{pspicture}(3,1)
  \optcoupler[fiber=t](0,1)(0,0)(3,1)(3,0)
\end{pspicture}
\end{LTXexample}
\begin{LTXexample}[morekeywords={[21]{fiber}}]
\begin{pspicture}(3,1)
  \wdmsplitter[fiber=br](0,0.5)(3,1)(3,0)
\end{pspicture}
\end{LTXexample}
\begin{LTXexample}[morekeywords={[21]{fiber}}]
\begin{pspicture}(3,1)
  \optcirculator[fiber=b](0,0.5)(3,1)(1,0)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{enumerate}
%
%
% \ifENGLISH\subsection{Appearance of automatic fiber connections}\fi
% \ifGERMAN\subsection{Aussehen der automatischen Faserverbindungen}\fi
% \label{sec:drawfiber-auto-styles}
%
% \begin{figure}\centering
% \begin{pspicture}(0,-0.2)(12,4.4)
% \rput[lt](0,4.4){%
%   \pstree[levelsep=1.5cm, treesep=0.6, 
%           nodesep=4pt, arrows=<-, 
%           arrowinset=0, arrowscale=1.5]{\poeTR{Fiber}}{%
%     \pstree{\poeTR{FiberIn}}{%
%       \poeTR{FiberIn1} \poeTR{FiberIn2}%
%     }%
%     \pstree{\poeTR{FiberOut}}{%
%       \poeTR{FiberOut1} \poeTR{FiberOut2}%
%     }%
%   }%
%   \rput[l](-1,0|T-0){\ifGERMAN Grundstil\fi\ifENGLISH parent style\fi}
%   \rput[l](-1,0|T-0-0){%
%     \ifGERMAN
%       \parbox{\widthof{ausgehende Fasern}}{%
%         \RaggedRight eingehende und ausgehende Fasern}%
%     \fi
%     \ifENGLISH
%       \parbox{\widthof{outgoing fibers}}{%
%         \RaggedRight incoming and outgoing fibers}%
%     \fi
%   }
%   \rput[t](! \psGetNodeCenter{T-0-0-0} \psGetNodeCenter{T-0-0-1}
%              T-0-0-0.x T-0-0-1.x add 2 div T-0-0-0.y 0.4 sub){%
%     \ifGERMAN
%       \parbox{\widthof{Obere(1) oder untere(2)}}{%
%         \RaggedRight Obere(1) oder untere(2) eingehende Faser.}%
%     \fi
%     \ifENGLISH
%       \parbox{\widthof{Upper(1) or lower(2)}}{%
%         \RaggedRight Upper(1) or lower(2) incoming fiber.}%
%     \fi
%   }
%   \rput[t](! \psGetNodeCenter{T-0-1-0} \psGetNodeCenter{T-0-1-1}
%              T-0-1-0.x T-0-1-1.x add 2 div T-0-1-0.y 0.4 sub){%
%     \ifGERMAN
%       \parbox{\widthof{Obere(1) oder untere(2)}}{%
%         \RaggedRight Obere(1) oder untere(2) ausgehende Faser.}%
%     \fi
%     \ifENGLISH
%       \parbox{\widthof{Upper(1) or lower(2)}}{%
%         \RaggedRight Upper(1) or lower(2) outgoing fiber.}%
%     \fi
%   }
% }%
% \end{pspicture}
% \ifGERMAN
% \caption{Vererbungsdiagramm der PS-Stile für die automatischen
% Faserverbindungen. Sie sollten diese Stile mit \protect\Lcs*{addtopsstyle}
% oder den entsprechenden \opt{addto}\prm{style} Parametern ändern um die
% Vererbungslinie beizubehalten.}%
% \fi 
% \ifENGLISH
% \caption{Inheritance diagram for the psstyles used for the automatic fiber
% connections. These styles should be changed with \protect\Lcs*{addtopsstyle}
% or the respective \opt{addto}\prm{style} options to preserve the
% inheritance.}%
% \fi
% \label{fig:fiberstyles}
% \end{figure}
%
% \ifENGLISH
% The styles of all automatic fiber connections can be configured independently,
% they are all derived from the basic \Lstyle{Fiber} style which is described in
% \prettyref{sec:fiberappearance}.
% \fi
% \ifGERMAN
% Die Stile aller automatischen Faserverbindungen können separat konfiguriert
% werden, der zugrundeliegende Stil ist immer \Lstyle{Fiber}, der in
% \prettyref{sec:fiberappearance} beschrieben ist.
% \fi
%
% \begin{stylelist}
% \item[\smash{%
%   \begin{tabular}[t]{@{}r@{}}%
%     \opt{FiberIn}\\
%     \opt{FiberIn1}\\
%     \opt{FiberIn2}\\
%     \opt{FiberOut}\\
%     \opt{FiberOut1}\\
%     \opt{FiberOut2}
%   \end{tabular}}%
% ]%
% \xLstyle{FiberIn}\label{prm:FiberIn}%
% \xLstyle{FiberIn1}\label{prm:FiberIn1}%
% \xLstyle{FiberIn2}\label{prm:FiberIn2}%
% \xLstyle{FiberOut}\label{prm:FiberOut}%
% \xLstyle{FiberOut1}\label{prm:FiberOut1}%
% \xLstyle{FiberOut2}\label{prm:FiberOut2}%
% \ifENGLISH
% Style \Lstyle{FiberIn} applies to all input fibers, it inherits from
% \Lstyle{Fiber}. If the component has more than one input fiber they have the
% styles \Lstyle{FiberIn1} and \Lstyle{FiberIn2} which inherit from
% \Lstyle{FiberIn}. All output fibers have the style \Lstyle{FiberOut}, two
% output fibers have the styles \Lstyle{FiberOut1} and \Lstyle{FiberOut2} which
% inherit from \Lstyle{FiberOut}. See \prettyref{fig:fiberstyles} for an
% inheritance diagram of the styles. You must have in mind, that this
% inheritance is effective only if you use \Lcs*{addtopsstyle} to change the
% styles (see also below).
% \fi
% \ifGERMAN
% Der Stil \Lstyle{FiberIn} bezieht sich auf alle Eingangsfasern und erbt alle
% Eigenschaften von \Lstyle{Fiber}. Hat eine Komponente zwei davon, so können
% diese mit \Lstyle{FiberIn1} und \Lstyle{FiberIn2} angesprochen werden, die
% alles von \Lstyle{FiberIn} übernehmen. Entsprechend bezieht sich
% \Lstyle{FiberOut} auf alle Ausgangsfasern, falls es davon zwei gibt dann
% können diese mit \Lstyle{FiberOut1} und \Lstyle{FiberOut2} geändert
% werden. Siehe \prettyref{fig:fiberstyles} für ein Vererbungsdiagramm der
% Faserstile. Beachten Sie, dass diese Vererbung nur erhalten bleibt, falls die
% Stile nur mit \Lcs*{addtopsstyle} oder den entsprechenden
% \opt{addto}\prm{style} Parametern verändert werden.
% \fi
%
% \item[\smash{\begin{tabular}[t]{@{}r@{}}%
%   \opt{new}\prm{style}\\
%   \opt{addto}\prm{style}
%   \end{tabular}}]
%   \xLkeyword{newFiberIn}\xLkeyword{addtoFiberIn}
%   \xLkeyword{newFiberIn1}\xLkeyword{addtoFiberIn1}
%   \xLkeyword{newFiberIn2}\xLkeyword{addtoFiberIn2}
%   \xLkeyword{newFiberOut}\xLkeyword{addtoFiberOut}
%   \xLkeyword{newFiberOut1}\xLkeyword{addtoFiberOut1}
%   \xLkeyword{newFiberOut2}\xLkeyword{addtoFiberOut2} 
%   \ifENGLISH For every style two appropriate keys \opt{new}\prm{style} and
%   \opt{addto}\prm{style} are provided which can be used to change the styles
%   for single objects. This can be used to define own components
%   (\prettyref{sec:customcomp}) with respectively changed fiber connections or
%   to avoid explicit grouping.
%   \fi
%   \ifGERMAN Für jeden Faserstil werden zwei Parameter \opt{new}\prm{style} und
%   \opt{addto}\prm{style} bereitgestellt, mit denen die Stile für einzelne
%   Komponenten verändert werden können. Damit können neuen Komponenten mit
%   anderen voreingestellten Faserverbindungen definiert werden
%   (\prettyref{sec:customcomp}), oder explizite Gruppierung kann vermieden
%   werden.
%   \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{addtoFiberOut1}}]
\begin{pspicture}(3,2)
  \newpsobject{tapcoupler}{wdmsplitter}{%
    coupleralign=b, 
    addtoFiberOut1={arrows=->, arrowscale=1.2, arrowinset=0}}
  \tapcoupler(0,0.5)(3,1.5)(3,0.5){99/1}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{stylelist}
%
%
% \ifGERMAN\section{Zeichenebenen}\fi
% \ifENGLISH\section{Layers}\fi
% \label{sec:layers}
% 
% \ifENGLISH 
% The necessary order of constructing a drawing is to define the components
% first before you can connect them. This implies that all connections are drawn
% on top of the components, which might be unwanted.
%
% To circumvent this, we provide the \Lenv{optexp} environment, inside which all
% connections are drawn behind the components.
% \fi
% \ifGERMAN
% Die Reihenfolge der Konstruktion einer Skizze ist die, dass zuerst die
% Komponenten definiert werden müssen, bevor diese verbunden werden können. Das
% beinhaltet aber, dass alle Verbindungen über die Komponenten gezeichnet
% werden, was nicht erwünscht sein muss.
%
% Um das zu vermeiden, wird die \Lenv{optexp}-Umgebung bereitgestellt, innerhalb
% derer alle Verbindungen hinter die Komponenten gelegt werden.
% \fi
%
% \begin{ltxsyntax}
%   \envitem{optexp}
% \end{ltxsyntax}
%
% \iffalse
%<*ignore>
% \fi
\ifENGLISH
\begin{LTXexample}
\begin{pspicture}(3,4)
  \psset{beam, fillstyle=solid, fillcolor=black}
  \optbox(0,3.5)(3,3.5){no layers}
  \begin{optexp}
    \optbox(0,1.5)(3,1.5){with layers}
  \end{optexp}
\end{pspicture}
\end{LTXexample}
\fi
\ifGERMAN
\begin{LTXexample}
\begin{pspicture}(3,4)
  \psset{beam, fillstyle=solid, fillcolor=black}
  \optbox(0,3.5)(3,3.5){ohne Ebenen}
  \begin{optexp}
    \optbox(0,1.5)(3,1.5){mit Ebenen}
  \end{optexp}
\end{pspicture}
\end{LTXexample}
\fi
% \iffalse
%</ignore>
% \fi
% 
% \ifENGLISH
% Beware, that this is achieved by executing twice all code included in the
% environment. This works fine for all \LPack{pst-optexp} commands which take
% care of not drawing stuff twice but only in a changed order. All other text
% and graphics are drawn twice which leads to ugly results because of altered
% anti-aliasing in the viewer.
%
% To avoid this, you can either move all other code outside the environment, or
% use the following two commands to define code parts which are executed only
% once.
% \fi
% \ifGERMAN
% Beachten Sie, dass das erreicht wird, indem der gesamte Code innerhalb der
% Umgebung doppelt ausgeführt wird. Das funktioniert mit allen
% \LPack{pst-optexp}-Makros, da diese sich intern darum kümmern nichts doppelt
% sondern nur in geänderter Reihenfolge zu zeichnen. Alle anderen Zeichnungen
% und Texte werden zweimal gezeichnet, was zu unschönen Ergebnissen aufgrund
% von geändertem Antialiasing in dem Betrachter führen kann.
%
% Um zu verhindern, dass anderer Code doppelt ausgeführt wird, muss dieser
% entweder außerhalb der \Lenv{optexp}-Umgebung definiert werden, oder durch
% eins der beiden folgenden Makros auf eine Ebene beschränkt werden.
% \fi
%
% \begin{ltxsyntax}
%   \cmditem{backlayer}{code} 
%
%   \ifENGLISH Execute \prm{code} only once in the first pass.\fi
%   \ifGERMAN Führe \prm{code} nur beim ersten Durchgang aus.\fi
%
%   \cmditem{frontlayer}{code}
%
%   \ifENGLISH Execute \prm{code} only once in the second pass.\fi
%   \ifGERMAN Führe \prm{code} nur beim zweiten Durchgang aus.\fi
% \end{ltxsyntax}
%
% \ifENGLISH
% In this example, the text is put on top of the frame although the text is
% defined first: 
% \fi
% \ifGERMAN In diesem Beispiel wird der Text über dem Rechteck angezeigt, obwohl
% der Text zuerst definiert wird:
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1)
\begin{optexp}
  \frontlayer{\rput(1.5,0.5){front}}
  \backlayer{\psframe*[linecolor=DOrange!50](1,0)(2,1)}
\end{optexp}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% 
% \ifGERMAN\chapter{Benutzerdefinierte Komponenten}\fi
% \ifENGLISH\chapter{Custom components}\fi
% \label{chap:custom}
%
% \ifGERMAN
% Das \LPack{pst-optexp}-Paket stellt zwei Makros zur Verfügung um
% eigene Komponenten zu zeichnen. Diese können z.B. aus Bildern oder
% eigenen Zeichnungen bestehen.
% \fi
% \ifENGLISH
% The \nxLPack{pst-optexp} package provides two commands which can use
% anything as optical components. This includes e.g. external images or
% your own drawings.
% \fi
% 
% \begin{ltxsyntax}
%   \dipoledesc{optdipole}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,3)
  \optdipole[labeloffset=1, beam](0,2)(3,1){%
    \rput(0,0){\rule{0.5cm}{1cm}}%
  }{label}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \tripoledesc{opttripole}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,3)
  \opttripole[beam](3,1.5)(1.5,2)(0,0){%
    \rput[b](0,0){text}%
  }{label}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
%
% \ifENGLISH
% These components can also be connected with beams and fibers, but do
% not provide full access to all options. \Lcs{opttripole} defines a
% single reflective interface, whereas \Lcs{optdipole} can have two
% transmittive interfaces:
% \fi
% \ifGERMAN
% Diese Komponenten können sowohl mit Fasern als auch mit Strahlen
% verbunden werden, können aber nicht deren volles Potential
% ausschöpfen. \Lcs{opttripole} definiert eine einzelne reflektive
% Grenzfläche, \Lcs{optdipole} kann zwei transmittive Grenzflächen haben:
% \fi
%
% \begin{optionlist}
%   \optitem[0 0]{optdipolesize}{\prm{width}[ \prm{height}]}
%   \ifGERMAN 
%   Hiermit können zwei transmittierende Grenzflächen für
%   \Lcs{optdipole} definiert werden, die sich bei
%   $(\pm 0.5\text{\prm{width}}, 0)$ befinden.
%   \fi
%   \ifENGLISH
%   With this option you can define two transmittive interfaces for
%   \Lcs{optdipole}, which are placed at $(\pm 0.5\text{\prm{width}}, 0)$.
%   \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]optdipolesize}]
\begin{pspicture}(3,2)
\pnode(0,1){A}\pnode(3,1){B}
\optdipole[optdipolesize=1, showifcnodes](A)(B){%
  \psframe[fillstyle=solid,fillcolor=black!30](-0.5,-0.5)(-0.3,0.5)
  \psframe(-0.5,-0.5)(0.5,0.5)}{label}
\drawwidebeam[beamwidth=0.3, beaminside=false](A){}(B)
\drawbeam[beaminside=false, linecolor=red](A){}(B)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN Wenn zusätzlich eine Höhe \prm{height} ungleich Null
% angegeben wird, so wird diese als Apertur für das Raytracing genommen
% (siehe \Lkeyword{useNA}). Im folgenden Beispiel ist die Höhe gleich
% \opt{0.2} und damit kleiner als der aufgeweitete Strahl der deshalb
% anders als im vorangegangenen Beispiel nicht gezeichnet wird.
% \fi
% \ifENGLISH 
% If also a \prm{height} greater than zero is set, this is used as size
% of the numerical aperture for ray tracing (see \Lkeyword{useNA}). In
% the following example the height is set to \opt{0.2} which is smaller
% than the wide beam which is not drawn, in contrast to the previous
% example.
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]optdipolesize}]
\begin{pspicture}(3,2)
\pnode(0,1){A}\pnode(3,1){B}
\optdipole[optdipolesize=1 0.2, showifcnodes](A)(B){%
  \psframe[fillstyle=solid,fillcolor=black!30](-0.5,-0.5)(-0.3,0.5)
  \psframe(-0.5,-0.5)(0.5,0.5)}{label}
\drawwidebeam[beamwidth=0.3, beaminside=false](A){}(B)
\drawbeam[beaminside=false, linecolor=red](A){}(B)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN  
% Weitere Beispiel sind \prettyref{ex:lclv} und
% \prettyref{ex:absspektr}.
% \fi
% \ifENGLISH 
% Further examples are \prettyref{ex:lclv} and
% \prettyref{ex:absspektr}.
% \fi
% \end{optionlist}
%
% \ifGERMAN
% \section{Benutzerdefinierte Version existierender Komponenten}
% \fi
% \ifENGLISH
% \section{Customized versions of existing components}
% \fi
% \label{sec:customcomp}
% 
% \ifENGLISH
% You can define a customized version of an existing component using the
% \Lcs*{newpsobject} macro. With this you can define a new component using
% predefined objects with a set of options. These options serve only as default
% values and can be overridden when calling the macro.
% \fi
% \ifGERMAN
% Sie können eine benutzerdefinierte Version einer existierenden Komponente mit
% \Lcs*{newpsobject} definieren, die z.B. andere Voreinstellungen oder und ein
% anderes Aussehen hat.
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{newpsobject}}]
\begin{pspicture}(3,1.7)
\newpsobject{sbn}{crystal}{%
  voltage, lamp, %
  fillstyle=solid, fillcolor=yellow!90!black}
\sbn[label=1.2 45, beam](0,1)(3,1){SBN:Ce}
\end{pspicture}
\end{LTXexample}

\begin{LTXexample}[morekeywords={[21]{newpsobject}}]
\begin{pspicture}(3,1.7) 
\newpsobject{pumpcoupler}{wdmcoupler}{%
  coupleralign=top, addtoFiberIn2={ArrowInside=->, arrowscale=2}}
\pumpcoupler[label=0.5 180](0,1)(0,0)(3,1){Pumpcoupler}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[pos=t, morekeywords={[21]{newpsobject}}, caption={caption}]
\begin{pspicture}(10,2)
  \newpsobject{MOLensIn}{lens}{lens=0.5 0.5 0.5}
  \newpsobject{MOLensOut}{lens}{lens=1.5 1.5 1.5}
  \pnode(0,1){A}\pnode(10,1){B}
  \MOLensIn[abspos=1](A)(B)\MOLensOut[abspos=2](A)(B)
  \optplate[plateheight=1.5](A)(B)
  \MOLensOut[abspos=8](A)(B)\MOLensIn[abspos=9](A)(B)
  \addtopsstyle{Beam}{n=1, fillstyle=solid, fillcolor=green, opacity=0.3}
  \psset{loadbeampoints}
  \drawwidebeam[beamwidth=0.2, stopinside](A){1}
  \drawwidebeam[beamdiv=-70]{1}{2}
  \drawwidebeam[stopinside]{2-4}
  \drawwidebeam[beamdiv=-70]{4}{5}
  \drawwidebeam{5}(B)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifENGLISH\section{Defining new objects}\fi
% \ifGERMAN\section{Neue Objekte definieren}\fi
% \label{sec:newobj}
%
% \ifENGLISH
% \nxLPack{pst-optexp} provides some high-level macros to allow very convenient
% definition of your own custom components. 
%
% Note, that this part of the documentation is not complete. It roughly
% describes the steps to define own components as of version 3.0. Some parts may
% be subject to change which are not backward compatible.
%
% The old syntax of defining \Lcs*{mycomp@iii} is supported for backward
% compatibility, but will be dropped soon. Please adapt your macros to the new
% syntax.
% \fi
% \ifGERMAN
% \nxLPack{pst-optexp} stellt einige Benutzermakros zur Verfügung, mit denen
% sehr bequem neue, eigene Komponenten definiert werden können.
%
% Beachten Sie, dass dieser Teil der Dokumentation nicht vollständig ist. Die
% notwendigen Schritte zur Definition neuer Komponenten in Version 3.0 werden
% grob beschrieben, können sich aber noch ändern und sind nicht zwangsläufig
% abwärtskompatibel.
%
% The alte Syntax mit \Lcs*{mycomp@iii} wird noch unterstützt, gilt aber als
% veraltet und wird in zukünftigen Versionen entfernt werden. Bitte passen Sie
% ihre vorhandenen Makros entsprechen an.
% \fi
%
% \begin{ltxsyntax}
%   \xLcs{newOptexpDipole}\cmditem{newOptexpDipole}[fixopt]{name}{dftopt}
%   \xLcs{newOptexpTripole}\cmditem{newOptexpTripole}[fixopt]{name}{dftopt}
%   \xLcs{newOptexpFiberDipole}\cmditem{newOptexpFiberDipole}[fixopt]{name}{dftopt}
% \end{ltxsyntax}
%
% \ifENGLISH
% These macros generate all organizing code for the components which handle the
% positioning, label placement, rotation and shifting, and the layering. In the
% simplest case you only have to define the actual drawing of the component
% outline.
%
% The macro \Lcs*{newOptexpDipoleNolabel} is superfluous because since version
% 3.0 the label is optional for all components.
%
% The actual process of creating a new component is split up in different parts,
% depending on the component complexity and user requirements:
% \begin{enumerate}
% \item The component drawing (see \prettyref{sec:newobj-comp}), this is the
%   only required part.
% \item Support for raytracing and layers (optional)
% \item Optional support for \Lkeyword{rotateref}, \Lkeyword{extnode} and
%   \Lkeyword{position}\opt{=start|end}.
% \end{enumerate}
% \fi
% \ifGERMAN
% Diese Makros erzeugen den Code für die Positionierung, Drehung, Beschriftung
% und die Ebenenverwaltung. Im einfachsten Fall müssen Sie lediglich die
% eigentliche Zeichnung der Komponente erstellen.
%
% Seit Version 3.0 ist das Makro \Lcs*{newOptexpDipoleNolabel} überflüssig, da
% seitdem die Beschriftung für alle Komponenten optional ist.
% 
% Die Definition der neuen Komponenten kann in unterschiedliche Schritte
% eingeteilt werden, je nach Komplexität und Anforderung des Benutzers:
%
% \begin{enumerate}
% \item Die Zeichnung (siehe \prettyref{sec:newobj-comp}), das ist der einzige
%   erforderliche Schritt.
% \item Unterstützung von Raytracing und Ebenen (optional).
% \item Unterstützung für \Lkeyword{rotateref}, \Lkeyword{extnode} und
%   \Lkeyword{position}\opt{=start|end}.
% \end{enumerate}
% \fi
%
% \ifENGLISH\subsection{The component drawing}\fi
% \ifGERMAN\subsection{Die Zeichnung der Komponente}\fi
% \label{sec:newobj-comp}
%
% \ifENGLISH
% You must define a macro which is called e.g. \cs{\ldots @comp}, which
% contains the component drawings. See the following two examples for dipole and
% tripole which show the orientation and position of the component coordinate
% system.
% \fi
% \ifGERMAN Sie müssen ein Makro \cs{\ldots @comp} definieren, welches
% die Zeichnung enthält. In den folgenden Beispielen sehen Sie die Ausrichtung
% und Position des Koordinatensystems für einen Zweipol und einen Dreipol.
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{newOptexpDipole}}]
\begin{pspicture}(3.5,2.6)
\newOptexpDipole{mydipole}{}
\makeatletter
\def\mydipole@comp{%
  \psaxes[arrows=->](0,0)(0,-1.1)(1.3,1.3)[$x$,90][$y$,0]
}%
\makeatother
\mydipole(0,1)(3.5,1){\color{spot}label}
\drawbeam(0,1){}(3.5,1)
\end{pspicture}
\end{LTXexample}
\begin{LTXexample}[morekeywords={[21]{newOptexpTripole}}]
\begin{pspicture}(3.5,3.7)
\newOptexpTripole{mytripole}{labelangle=-60}
\makeatletter
\def\mytripole@comp{%
  \psaxes[arrows=->](0,0)(-1.1,0)(1.3,1.3)[$x$,90][$y$,0]
}%
\makeatother
\mytripole(0,1)(2,1.7)(3,0){\color{spot}label}
\drawbeam(0,1){}(3,0)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN
%   \chapter{Beispiele}
% \fi
% \ifENGLISH
%   \chapter{Examples}
% \fi
% \label{sec:examples}
% \iffalse
%<*ignore>
% \fi
\enlargethispage{1.5cm}
\begin{LTXexample}[pos=t, caption={caption}]
\begin{pspicture}(0.1,0.4)(10,4.5)
  \psset[optexp]{lens=1 1 0.7, loadbeampoints}
  \pnode(2,4){L}\pnode([Xnodesep=4]L){M}
  \pnode([Xnodesep=1.5]M){IRSpec}\pnode([offset=-2.5]M){OSA}
  \begin{optexp}
  \optbox[position=start, innerlabel, optboxwidth=1.8](L)(M){fs laser}
  \lens[abspos=1](L)(M)
  \optbox[abspos=1.85, optboxsize=0.7 0.15, fillstyle=solid, fillcolor=black](L)(M){sample}
  \lens[abspos=2.7](L)(M)
  \mirror[labelangle=45](L)(M)(OSA){flip mirror}
  \optbox[position=end, optboxsize=3.2 1, innerlabel, compshift=-0.2](M)(IRSpec){IR spectrometer}
  \lens[abspos=1](M)(OSA)
  \optplane[angle=90]([offset=-1.5]M)
  \optfiber[fiberloopradius=0.2, fiberloopsep=0.2, label=1, newFiber={linewidth=1.5\pslinewidth}]([offset=-1.5]M)(OSA){MM fiber}
  \optbox[position=end, innerlabel, optboxwidth=1.1](M)(OSA){OSA}
  \newpsstyle{Beam}{linestyle=none, fillcolor=red, fillstyle=solid, raytrace=false}
  \drawwidebeam[beamwidth=0.2, stopinside]{1-2}
  \drawwidebeam[beamdiv=-25]{2-3}
  \drawwidebeam[loadbeampoints=false, beamdiv=25]{3-4}
  \drawwidebeam[startinside]{4-5}
  \drawwidebeam[savebeampoints=false, beamalign=abs]{5-6}
  \drawwidebeam[stopinside]{5}{7}
  \drawwidebeam[beamdiv=-25]{7-8}
\end{optexp}
\end{pspicture}
\end{LTXexample}

\begin{LTXexample}[pos=t, caption={caption}]
\begin{pspicture}(-4.2,-1)(3,3)
\pnode(-2,0){LOut}\pnode(0,0){Grat}\pnode(4;45){Out}\pnode(2.5;70){Mvar}
\newpsstyle{Beam}{linewidth=2\pslinewidth, linecolor=red!90!black}
\begin{optexp}
  \optbox[optboxwidth=2.2, labeloffset=0, position=start](LOut)(Grat){diode laser}
  \mirror[variable, label=0.5](Grat)(Mvar)(Grat){M$_\mathrm{var}$}
  \optretplate[position=0.3](LOut)(Grat){$\nicefrac{\lambda}{4}$}
  \optgrating(LOut)(Grat)(Out){grating}
  \drawbeam[arrows=->]{1}{3}{4}(Out)
  \drawbeam{2}{4}
\end{optexp}
\rput[l](-3,2){Littman setup}
\end{pspicture}
\end{LTXexample}
\bigskip

\begin{LTXexample}[pos=t, caption={caption}]
\begin{pspicture}(8.5,1.9)
\pnode(1.4,1.3){Laser}\pnode(7.6,1.3){Diode}
\optbox[position=start, labeloffset=0](Laser)(Diode){Laser}%
\optbox[abspos=4, optboxsize=1 0.6, labeloffset=1, n=3,
        compname=PC, angle=-10, rotateref=l](Laser)(Diode){Photonic Crystal}
\optdetector[dettype=diode](\oenodeOut{PC})(Diode|\oenodeOut{PC}){PD}
\nodexn{(\oenodeIn{PC}) + (2;170)}{Angle1}
\psline[linestyle=dashed](\oenodeIn{PC})(Angle1)
\psarc{<->}(\oenodeIn{PC}){1.3}{330}{30}
\psarc[arcsep=1pt]{<->}(\oenodeIn{PC}){2}{170}{180}
\uput{2.1}[175](\oenodeIn{PC}){\small $\varphi$}
\drawbeam{-}
\end{pspicture}
\end{LTXexample}
\bigskip

\enlargethispage{2cm}
\begin{LTXexample}[pos=t, caption={caption}]
\begin{pspicture}(10.4,1.7)
\pnode(1.2,1){Start}\pnode(9.2,1){CCD}
\begin{optexp}
\optbox[position=end, label=0, optboxwidth=1.2](CCD)(Start){Laser}
\optbox[position=end, label=0, optboxwidth=1.2](Start)(CCD){CCD}
\polarization[poltype=perp,abspos=0.5](Start)(CCD)
\optretplate[abspos=1](Start)(CCD){$\nicefrac{\lambda}{2}$}
\lens[lens=0.4 0.4 0.5,abspos=2](Start)(CCD){$L_1$}
\lens[abspos=4](Start)(CCD){$L_2$}
\optplate[abspos=6, platelinewidth=3\pslinewidth](Start)(CCD){SLM}
\optplate[abspos=6.5, labelangle=180](Start)(CCD){PF}
\polarization[abspos=6.7](Start)(CCD)
\lens[abspos=7](Start)(CCD){$L_3$}
\drawbeam[linewidth=2\pslinewidth]{1}{2}
\end{optexp}
\end{pspicture}
\end{LTXexample}
\medskip

\begin{LTXexample}[pos=t, caption={caption}]
\begin{pspicture}(10.4,1.7)
\pnode(1.2,1){Start}\pnode(9.2,1){CCD}
\begin{optexp}
\optbox[position=start, label=0, optboxwidth=1.2](Start)(CCD){Laser}
\polarization[poltype=perp,abspos=0.5](Start)(CCD)
\optretplate[abspos=1](Start)(CCD){$\nicefrac{\lambda}{2}$}
\lens[lens=0.4 0.4 0.5,abspos=2](Start)(CCD){$L_1$}
\pinhole[phwidth=0.05, abspos=2.35, labelangle=180](Start)(CCD){iris}
\lens[abspos=4](Start)(CCD){$L_2$}
\optplate[abspos=6,platelinewidth=3\pslinewidth](Start)(CCD){SLM}
\optplate[abspos=6.5,labelangle=180](Start)(CCD){PF}
\lens[abspos=7](Start)(CCD){$L_3$}
\optbox[position=end, label=0, optboxwidth=1.2](Start)(CCD){CCD}
\polarization[abspos=6.7, polsize=0.8](Start)(CCD)
\addtopsstyle{Beam}{fillstyle=solid, fillcolor=green!40!white, loadbeampoints}
\drawwidebeam[beamwidth=0.1, stopinside]{1}{4}
\drawwidebeam[beamdiv=-20]{4}{6}
\drawwidebeam[stopinside]{6-9}
\drawwidebeam[beamdiv=-30]{9-10}
\end{optexp}
\end{pspicture}
\end{LTXexample}
\bigskip

\enlargethispage{2cm}
\begingroup
\captionsetup[lstlisting]{format=poecaption}
\begin{LTXexample}[pos=t, caption={\ifGERMAN Angepasst von \fi\ifENGLISH Adapted from \fi\arxivurl{1112.5270v2}}]
\begin{pspicture}(0.3,0.4)(5.5,8.3)
\pnode(2,7){L}\pnode(2,5.8){Pbs}\pnode([Xnodesep=1]Pbs){Blk1}\pnode(2,2.3){Bs}
\pnode([Xnodesep=-1]Bs){Blk2}\pnode([Xnodesep=3.5]Bs){Out}\pnode(2,1.3){Slm}
\begin{optexp}
  \optbox[position=end, innerlabel, optboxsize=1.2 0.6](Pbs)(L){Laser}
  \psset{labelalign=r, mirrortype=extended}
  \newpsstyle{ExtendedMirror}{fillstyle=solid, fillcolor=black}
  \optretplate[position=0.4](L)(Pbs){HWP}
  \beamsplitter[labelangle=-90](L)(Pbs)(Blk1){PBS}
  \mirror[label=. -90 c](Pbs)(Blk1)(Pbs){B}
  \lens[abspos=0.8, lens=0.7 0.7 0.7, n=2](Pbs)(Bs){MO}
  \pinhole[phwidth=0.15, abspos=1.2](Pbs)(Bs){PH}
  \lens[abspos=2.6, lensradius=1.4](Pbs)(Bs){L}
  \psset{labelalign=c}
  \beamsplitter[labelangle=-135](Pbs)(Bs)(Blk2){BS}
  \mirror[labeloffset=0.4](Bs)(Blk2)(Bs){B}
  \lens[abspos=1, lensradius=1.4](Bs)(Out){L}
  \lens[abspos=2.8, lens=0.7 0.7 0.7, n=2](Bs)(Out){L}
  \opttripole(Bs)(Slm)(Bs){%
    \psframe[fillstyle=solid,fillcolor=gray!50](-0.3,0)(0.3,0.2)
    \psline(-0.3,0.1)(-0.5,0.1)(-0.5,0.5)(0.5,0.5)(0.5,0.1)(0.3,0.1)}{SLM}
  \addtopsstyle{Beam}{linestyle=none, fillstyle=solid, fillcolor=green!70!black}
  \drawwidebeam[beamwidth=0.1]{1-4}
  \drawwidebeam[beamwidth=0.1, beaminsidefirst, beaminsidelast]{3}{5-8}
  \psset{savebeampoints=false, loadbeampoints}
  \drawwidebeam{8-11}(Out)\drawwidebeam[beaminsidefirst]{8}{12}
\end{optexp}
\end{pspicture}
\end{LTXexample}
\endgroup

\begin{LTXexample}[pos=t, caption={caption}]
\begin{pspicture}(6.4,3.2)
\addtopsstyle{Fiber}{linecolor=red}\psset{fiber=none}
\pnode(2.3,2.3){Lin}\pnode([Xnodesep=4.5]Lin){Det}
\optbox[label=0.2, position=start, compname=L, extnode=b](Lin)(Det){%
  \psGauss[yunit=0.03,sigma=0.03]{-0.5}{0.5}}
\optbox[label=0, compname=EAM, extnode=b, abspos=1.5](Lin)(Det){EAM}
\optfiber[labeloffset=0.3, abspos=3.2](Lin)(Det){fibre}
\optdetector(Lin)(Det){OSA}
\pnode([Xnodesep=-1,offset=-1]\oenodeExt{L}){Osc}
\pnode(\oenodeExt{L}|Osc){PSin}\pnode(\oenodeExt{EAM}|Osc){PSout}
\oscillator[output=right](Osc){10\,GHz}{}
\phaseshifter[arrowscale=1.5, inputarrow, labeloffset=-0.7](PSin)(PSout){$\tau$}
\drawfiber{1}{2}{3}{4}
\psset{arrows=->, arrowinset=0, arrowscale=1.5}
\wire(PSin)(\oenodeExt{L})\wire(PSout)(\oenodeExt{EAM})
\end{pspicture}
\end{LTXexample}

\enlargethispage{1cm}
\begin{LTXexample}[pos=t, caption={caption}]
\begin{pspicture}(0.2,0.6)(8.2,3.5)
\pnode(2,3){Laser}\pnode(2,1){PwMeter}\pnode(6,3){CplTop}\pnode(6,1){CplBot}
\psset{arrowscale=1.5, arrowinset=0}
\optbox[position=start, optboxsize=1.8 1, labeloffset=0](Laser)([Xnodesep=0.1]Laser){%
  \begin{tabular}{@{}c@{}}Nd:YAG\\[-0.4ex]cw laser\end{tabular}}
\optcoupler[addtoFiberIn1={ArrowInside=->}, addtoFiberIn2={ArrowInside=-<},
            labeloffset=0.4](Laser)(PwMeter)(CplTop)(CplBot){WDM}
\optfiber[addtoFiberOut={ncurv=1, angleB=0}, addtoFiberIn={ncurv=1, angleA=0}, 
          compshift=-1, label=0.2 . l](CplBot)(CplTop){fiber}
\optdetector[dettype=diode]([Xnodesep=0.1]PwMeter)(PwMeter){power meter}
\end{pspicture}
\end{LTXexample}

\begin{LTXexample}[pos=t, caption={caption}]
\begin{pspicture}(0.9,0.9)(10.4,6.1)
\psset{arrowscale=1.5, arrowinset=0}
\pnode(2,5){PC1in}\pnode(4,5){PC1out}\pnode(6,5){PC2in}
\pnode(8,5){PC2out}\pnode(2,2){CplSig}\pnode(5,2){CplIn}
\pnode(2,1){CplOut}\pnode(10,4.5){Pump}\pnode(8,2){PumpSig}
\optisolator[compshift=0.8, addtoFiberIn={angleA=180}, 
             addtoFiberOut={angleB=180}, label=0.5 . l]%
             (CplSig)(PC1in){isolator}
\polcontrol[addtoFiberIn={arrows=|-}](PC1in)(PC1out)
\optfiberpolarizer[labeloffset=0.6](PC1out)(PC2in){polarizer}
\polcontrol[addtoFiberOut={arrows=-|}](PC2in)(PC2out)
\wdmsplitter[labeloffset=0.3, coupleralign=bottom, addtoFiberIn={arrows=|-}, 
             addtoFiberOut1={arrows=->}, addtoFiberOut2={arrows=-|}]%
             (CplIn)(CplOut)(CplSig){95/5}
\wdmcoupler[addtoFiberIn1={ArrowInside=->}, addtoFiberIn2={angleA=0}, 
            addtoFiberOut={angleB=0,arrows=-|}, ncurv=0.9, 
            coupleralign=bottom, compshift=0.8](Pump)(PC2out)(PumpSig){pump}
\optbox[position=start, innerlabel, optboxwidth=1.6](Pump)([offset=-0.1]Pump){980~nm}
\optfiber[fiberloops=2, labeloffset=0.4](CplIn)(PumpSig){Er$^+$-doped}
\end{pspicture}
\end{LTXexample}
\bigskip

\begin{LTXexample}[pos=t, caption={caption}]
\begin{pspicture}(1,1.2)(6.2,5)
\pnode(1,4){SigIn}\pnode(3,4){BS}\pnode(3,5){LO}
\pnode(5,4){Det1}\pnode(3,2){Det2}
\begin{optexp}
  \optplane[compname=LO, angle=90](LO)
  \beamsplitter[compname=BS](SigIn)(BS)(Det2)
  \lens[abspos=0.5, compname=L2, n=2.1](Det2)(BS){$L_2$}
  \lens[abspos=0.5, compname=L1, n=2.1](Det1)(BS){$L_1$}
  \psset[optexp]{extnodealign=rel, extnode=r}
  \optdetector[compname=Det1](BS)(Det1){PD1}
  \optdetector[compname=Det2](BS)(Det2){PD2}
  \addtopsstyle{Beam}{beamwidth=0.2, fillstyle=solid, 
                        fillcolor=green, opacity=0.2}
  \drawwidebeam(SigIn){BS}{L2}{Det2}
  \drawwidebeam[beaminsidefirst]{BS}{L1}{Det1}
  \newpsstyle{Beam}{linecolor=red, linestyle=dashed, linewidth=1.5\pslinewidth}
  \drawbeam{LO}{BS}{L1}{Det1}
  \drawbeam[beaminsidefirst]{BS}{L2}{Det2}
\end{optexp}
\cnodeput[framesep=5pt]([Xnodesep=0.5, offset=-0.5]\oenodeExt{Det1}|\oenodeExt{Det2}){M}{\rule{2.5mm}{1pt}}
\psset{arrows=<-, arrowscale=1.5, arrowinset=0}
\nccurve[angleA=90]{M}{\oenodeExt{Det1}}
\nccurve[angleA=180, angleB=-90]{M}{\oenodeExt{Det2}}
\end{pspicture}
\end{LTXexample}
\bigskip

\begin{LTXexample}[pos=t, caption={caption}, label={ex:lclv}]
\begin{pspicture}(-0.2,0)(9,5)
\psset[optexp]{lens=1.2 0 1.2, n=1.72}
\addtopsstyle{Beam}{fillstyle=solid, fillcolor=green, opacity=0.3}
\pnode(2.4,1){BS1}\pnode([offset=3]BS1){M1}
\pnode([Xnodesep=5.5]M1){PP}\pnode(PP|BS1){BS2}
\begin{optexp}
  \optbox[label=0, position=start, optboxwidth=1.6]([Xnodesep=-1]BS1)(BS1){Nd:YAG}
  \beamsplitter[compname=BS](BS2)(BS1)(M1){BS}
  \optdipole[position=0.2, compname=LCLV, optdipolesize=0.28 1](BS1)(BS2){%
    \psframe[fillstyle=solid,fillcolor=black,dimen=outer](-0.14,-0.5)(-0.02,0.5)
    \psframe[fillstyle=solid,fillcolor=gray!50,dimen=outer](-0.02,-0.5)(0.14,0.5)
  }{LCLV}
  \optretplate(BS1)(M1){P}
  \mirror(BS1)(M1)(PP){M}
  \lens[position=0.2](M1)(PP){L}
  \pinhole(M1)(PP)
  \lens[position=0.2](PP)(M1){L}
  \pentaprism(M1)(PP)(BS2){PP}
  \beamsplitter(PP)(BS2)(BS1){BS}
  \doveprism[compname=Dove, position=0.27, n=2.3](BS2)(BS1){Dove}
  \lens[n=2.5](BS2)(BS1){L}
  \drawwidebeam[beamwidth=0.3]{1-3}
  \drawwidebeam[loadbeampoints]{3}{2}{4-}{3}
\end{optexp}
\end{pspicture}
\end{LTXexample}

\enlargethispage{1cm}
\begin{LTXexample}[pos=t, caption={caption}]
\begin{pspicture}(0,-0.2)(8.6,5.6)
\pnode(1.5,5){Laser}\pnode(4,5){PBS}\pnode(6.5,5){PBS2}\pnode(6.5,5.7){piezo}
\pnode(4,2){BSFwd}\pnode(6.5,2){BSBwd}\pnode(2,2){BS4f}\pnode(2,0.5){M4f3}
\pnode(8,2){M4f1}\pnode(8,0.5){M4f2}\pnode(1,2){CCD}
\psset{mirrorwidth=0.6, plateheight=0.7, outerheight=0.7, labeloffset=0.7, labelstyle=\scriptsize, lens=1.2 1.2 0.8, bssize=0.5} 
\optbox[position=start, optboxsize=1.5 0.7, innerlabel]% 
   (Laser)(PBS){\parbox{1.5cm}{\centering Nd:YAG\\ 532\,nm}}
\lens[lensheight=0.5, position=0.2](Laser)(PBS){MO}
\pinhole[position=0.3,labelangle=180](Laser)(PBS){PH}
\lens[position=0.5](Laser)(PBS){L}
\optretplate[position=0.8](Laser)(PBS){$\nicefrac{\lambda}{2}$}
\beamsplitter(Laser)(PBS)(BSFwd){PBS}
\optretplate[position=0.4](PBS)(BSFwd){$\nicefrac{\lambda}{2}$}
\polarization(PBS)(BSFwd)\polarization(PBS2)(BSBwd)
\lens[position=0.8](PBS)(BSFwd){L}
\optretplate(PBS)(PBS2){$\nicefrac{\lambda}{2}$}
\beamsplitter(PBS)(PBS2)(piezo){PBS}
\optretplate[abspos=0.5](PBS2)(piezo){$\nicefrac{\lambda}{4}$}
\mirror[mirrortype=piezo,labelangle=90](PBS2)(piezo)(PBS2){PZ}
\lens[position=0.8,labelangle=180](PBS2)(BSBwd){L}
\crystal[crystalsize=1 0.5, voltage, lamp, fillstyle=solid, fillcolor=yellow!90!black, labeloffset=0.8](BSFwd)(BSBwd){SBN:Ce}
\beamsplitter(PBS)(BSFwd)(BSBwd){BS}
\beamsplitter[labelangle=-90](PBS2)(BSBwd)(BSFwd){BS}
\mirror(BSBwd)(M4f1)(M4f2){M}\mirror(M4f1)(M4f2)(M4f3){M}
\lens[labelangle=180](M4f2)(M4f3){L}\mirror(M4f2)(M4f3)(BS4f){M}
\beamsplitter(M4f3)(BS4f)(CCD){BS}
\optbox[position=end, label=0, optboxwidth=1](BS4f)(CCD){CCD}
\lens[abspos=0.7](BS4f)(BSFwd){L}\lens[abspos=0.7](BSBwd)(M4f1){L}
\addtopsstyle{Beam}{linewidth=2\pslinewidth}
\drawbeam{1-6}{11-14}{13}{12}{15}{18}{16}{17}{25}{23}{24}
\drawbeam[beaminsidefirst]{6}{7}{10}{17}{16}{18}{26}{19-24}
\end{pspicture}
\end{LTXexample}

\bgroup
\psset{unit=0.9}
\begin{LTXexample}[pos=t, caption={caption}, label=ex:transmission-loop]
\begin{pspicture}(13,5.5)
\psset{usefiberstyle, optboxwidth=1, labelstyle=\footnotesize, fiber=none}
\pnode(1,5){LD}\pnode([Xnodesep=5.5]LD){CPLin1}
\pnode([offset=-2]CPLin1){CPLin2}\pnode([Xnodesep=2.5]CPLin1){CPLout1}
\pnode([Xnodesep=2.5]CPLin2){CPLout2}\pnode([Xnodesep=3]CPLout1){RX}
\optbox[position=start, label=0](LD)(CPLin1){LD}
\optmzm[abspos=0.8](LD)(CPLin1){MZM}
\optamp[abspos=2](LD)(CPLin1){EDFA}
\optfilter[abspos=3](LD)(CPLin1){BPF}
\optswitch[abspos=4](LD)(CPLin1){SW}
\polcontrol[abspos=5, fiber=out](LD)(CPLin1)
\drawfiber{1}{2}{3}{4}{5}{6}
\optcoupler[couplertype=none, fiber](CPLin1)(CPLin2)(CPLout1)(CPLout2)
\optamp[abspos=0.8, fiber=in](CPLout1)(RX){EDFA}
\optfilter[abspos=2](CPLout1)(RX){BPF}
\optbox[position=end](CPLout1)(RX){RX}
\drawfiber{8}{9}{10}
\pnode([Xnodesep=-0.5]LD|CPLin2){TL}\pnode(RX|TL){TR}
\pnode([offset=-2.5]TR){BR}\pnode(TL|BR){BL}
\optamp[fiber=i](CPLout2)(TR){EDFA}
\optfiber[label=0.3 . t, position=0.85](BL)(BR){SSMF 89.8~km}
\drawfiber[fiberstyle=angle, arm=1.2, linearc=0.5, startnode=N]{11}{12}
\optamp[position=0.3](BR)(BL){EDFA}
\optfilter[position=0.55, labelangle=180](BL)(BR){BPF}
\optfiber[fiberloops=1, label=0.3 . t, position=0.35](BL)(BR){DCF 16.2~km}
\optamp[position=0.85](BR)(BL){EDFA}
\optfilter[position=0.2](TL)(CPLin2){BPF}
\optswitch(TL)(CPLin2){SW}
\polcontrol[position=0.8, fiber=out](TL)(CPLin2)
\drawfiber{12}{13}{14}{15}{16}\drawfiber{17}{18}{19}
\drawfiber[fiberstyle=angle, arm=0.5, linearc=0.5, stopnode=1]{16}{17}
\end{pspicture}
\end{LTXexample}
\egroup

\enlargethispage{1cm}
\begin{LTXexample}[pos=t, caption={caption}]
\begin{pspicture}(12, 4)
  \psset{labeloffset=0.3, fiber=none}
  \pnode(1.6,2){In}\pnode(12, 2){Ref}
  \optplate[linestyle=dashed, plateheight=3, position=1, compname=RefPlane](In)(Ref)
  \addtopsstyle{Beam}{linestyle=none, beamdiv=20, beaminside=false, fillstyle=solid, fillcolor=red, opacity=0.3}
  \multido{\i=1+1, \ii=165+10}{4}{%
    \rput(Ref){\pnode(6;\ii){A\i}}
    \optbox[optboxsize=0.5 0.3, position=end, compname=Box\i, extnode=l](Ref)(A\i)
    \lens[lens=0 -0.6 0.6, abspos=0.5, compname=L\i](A\i)(Ref)
    \lens[lens=1.2 1.2 0.8, abspos=1.1, n=1.65, compname=LC\i](A\i)(Ref)
    \drawwidebeam{Box\i}{L\i}{LC\i}{RefPlane}
  }%
  \optcoupler[abspos=1](In)(In)(Ref)(Ref)
  \wdmsplitter[abspos=2.5, compshift=1](In)(Ref)(Ref)
  \wdmsplitter[abspos=2.5, compshift=-1](In)(Ref)(Ref)
  \optbox[compshift=-1, position=start, label=0](In)(Ref){Laser1}
  \optbox[compshift=1, position=start, label=0](In)(Ref){Laser2}
  \drawfiber{17}{14}{15}{Box1}\drawfiber{15}{Box2}
  \drawfiber{18}{14}{16}{Box3}\drawfiber{16}{Box4}
\end{pspicture}
\end{LTXexample}
\medskip

\begin{LTXexample}[caption={caption}]
\begin{pspicture}(0.5,0)(2.2,4)
  \pnode(0,1){A}\pnode(1,1){BS}\pnode(2,1){G}\pnode(1,4){B}
  \beamsplitter(G)(BS)(B)
  \optgrating(BS)(G)(BS)
  \lens[lens=2 2 1.5, compshift=0.1, n=2.25](BS)(B)
  \pinhole[phwidth=0.05, innerheight=0.05, position=0.8, compshift=0.18](BS)(B)
  \optplane[angle=90](B)
  \addtopsstyle{Beam}{linestyle=none, beamwidth=0.2, fillstyle=solid}
  \drawwidebeam[fillcolor=red!25!white](A){1-2}{1}{3-5}
  \drawwidebeam[fillcolor=red!50!white, beamangle=-5]{2}{1}{3-5}
\end{pspicture}
\end{LTXexample}

\begingroup
\captionsetup[lstlisting]{format=poecaption}
\begin{LTXexample}[pos=t, caption={\ifGERMAN Angepasst von \fi\ifENGLISH Adapted from \fi\href{http://de.wikipedia.org/w/index.php?title=Datei:Czerny-turner.png}{Wikipedia}}, label={ex:czerny-turner}]
\begin{pspicture}(0,-1)(8.5,4)
\psframe[fillstyle=solid,fillcolor=gray!90,linestyle=none](0,-1)(8.5,4)
\addtopsstyle{OptComp}{linecolor=white}
\newpsstyle{Beam}{ArrowInside=->, linejoin=2, arrowscale=1.3, arrowinset=0}
\addtopsstyle{ExtendedMirror}{hatchcolor=white, hatchsep=0.5\pslinewidth}
\pnode(0,3){A}\pnode(8,3){B}\pnode(3,1.5){C}\pnode(8,0){D}\pnode(0,0){E}%
\psset{linewidth=1.5\pslinewidth, mirrorradius=13,  mirrorwidth=1.5, gratingwidth=1.3, mirrortype=extended, phwidth=0.1, outerheight=1.5}%
\begin{optexp}
  \pinhole[position=0.2](A)(B)%
  \mirror(A)(B)(C)
  \optgrating[reverse, angle=15, variable](B)(C)(D)
  \mirror(C)(D)(E)
  \pinhole[position=0.8](D)(E)
  \drawwidebeam[ArrowInsidePos=0.3, beamwidth=0.2, linecolor=white, beamdiv=-7.15](A){1-3}
  \psset{loadbeampoints, savebeampoints=false}%
  \drawwidebeam[ArrowInsidePos=0.6, beamangle=3, linecolor=blue!60!white]{3-5}(E)
  \drawwidebeam[ArrowInsidePos=0.7, linecolor=green!60!white, arrows=->, ArrowInsideMinLength=2]{3-5}(E)
  \drawwidebeam[ArrowInsidePos=0.8, beamangle=-3, linecolor=red!60!white]{3-5}(E)
\end{optexp}
\end{pspicture}
\end{LTXexample}
\endgroup

\begin{LTXexample}[pos=t, caption={caption}]
\begin{pspicture}(0,0.7)(9.4,3.3)
  \psset[optexp]{couplertype=rectangle, fiber=none, detsize=0.5 0.6}
  \multido{\i=1+1}{3}{%
    \optbox[optboxsize=1.5 0.6, innerlabel,position=start](1.5,\i)(7,\i){Laser \i}
    \wdmsplitter[position=0.2](1.5,\i)(7,\i)(7,\i)
    \wdmcoupler[position=0.8](1.5,\i)(1.5,\i)(7,\i)
    \optdetector[label=0.4 90 l](1.5,\i)(7,\i){Detector \i}
  }%
  \drawfiber[linecolor=blue, startnode=N]{1}{2}{7}
  \drawfiber[linecolor=blue]{2}{11}
  \drawfiber[linecolor=green, stopnode=1]{5}{6}{11}
  \drawfiber[linecolor=green, stopnode=2]{6}{3}
  \drawfiber[linecolor=red]{9}{10}{3}
  \drawfiber[linecolor=red, startnode=2]{10}{7}
  \drawfiber[linecolor=cyan]{11}{12}
  \drawfiber[linecolor=magenta]{7}{8}
  \drawfiber[linecolor=yellow]{3}{4}
\end{pspicture}
\end{LTXexample}

\begin{LTXexample}[caption={caption}]
\begin{pspicture}(0,1)(3.2,4.2)
  \pnode(0,2){In}\pnode(1,2){G}\pnode(1,4){M1}
  \pnode(3,2){M2}\pnode(1,1){S}
  \mirror[mirrortype=semitrans](In)(G)(M1)
  \optbox[optboxwidth=0.15, angle=45, style=SemitransMirror](G)(M1)
  \mirror[mirrortype=extended](G)(M1)(G)
  \mirror[mirrortype=extended](G)(M2)(G)
  \optplate[position=end](G)(S)
  \newpsstyle{Beam}{linecolor=red, ArrowInside=->, ArrowInsidePos=0.4, arrowscale=1.3}
  \drawbeam(In){1}{4}{1}{5}
  \drawbeam(In){1-3}{2}{1}{5}
\end{pspicture}
\end{LTXexample}

\begingroup
\captionsetup[lstlisting]{format=poecaption}
\begin{LTXexample}[vsep=10mm, pos=t, caption={\ifENGLISH Adapted from \fi\ifGERMAN Angepasst von \fi\href{http://www.semibyte.de/wp/graphicslibrary/gl-physics/versuchsaufbauten-f-praktikum/}{semibyte.de}}]
\begin{pspicture}(13.6,2.6)
  \psset[optexp]{labeloffset=1, mirrorwidth=0.5, optboxwidth=2}
  \pnode(2,1){Laser}\pnode(12,2){Film}\pnode(Film|Laser){Ref}
  \begin{optexp}
    \optbox[position=start](Laser)(Ref){HeNe-Laser}
    \pinhole[abspos=0.8](Laser)(Ref){Blende}
    \optbox[abspos=2.5](Laser)(Ref){Raumfilter}
    \lens[fillstyle=solid, fillcolor={[rgb]{0.87,0.91,0.93}}](Laser)(Ref){Linse}
    \mirror[label=1 30]([offset=0.2]Laser)([offset=0.2]Ref)(Film){%
      \begin{tabular}{l}Spiegel\\(fest)\end{tabular}}
    \opttripole[label=0.4](Ref)(Film)(Ref){%
      \psframe(0.5,1\pslinewidth)(-0.5,5\pslinewidth)
      \psline[linewidth=2\pslinewidth](0.5,0)(-0.5,0)
    }{Film}
    \newpsstyle{Beam}{linewidth=2\pslinewidth, linecolor=red!90!black, beamalign=absolute}
    \drawbeam{1-4}
    \drawbeam[beampos=0.2]{4-6}
    \mirror[variable, label=0.8 -30]([offset=-0.2]Laser)([offset=-0.2, Xnodesep=-0.7]Ref)(Film){var. Spiegel}
    \drawbeam[beampos=-0.2]{4}{7}{6}
  \end{optexp}
\end{pspicture}
\end{LTXexample}
\endgroup

\begin{LTXexample}[pos=t, caption={caption}]
\begin{pspicture}(0,0.2)(6.6,3.1)
  \psset{mirrorwidth=0.6, useNA=false, beaminsidefirst}
  \pnode(0,2){In}\pnode(1,2){BS}\pnode(1,0.5){M1}\pnode(2,1){M2}\pnode(6,1.5){Det}
  \mirror[mirrortype=semitrans, n=1](In)(BS)(M1)
  \mirror[label=0.6 180 . absolute, compname=M](BS)(M1)(M2|M1)
  \mirror(M1)(M2|M1)(M2)
  \mirror(M2|M1)(M2)([Xnodesep=1]M2)
  \optbox[optboxsize=2 1, abspos=2, label=0, allowbeaminside=false](BS)([offset=0.5]Det){%
    \parbox{1.6\psxunit}{spectral\\filter ($\Omega$)}}
  \lens[lens=4 4 2, n=3.3]([Xnodesep=-3]Det)(Det)
  \optbox[optboxsize=0.2 0.6, n=1, label=-1.2](\oenodeOut{6})(Det){%
    \begin{tabular}{@{}c@{}}nonlinear\\ crystal\end{tabular}}
  \optplate[linestyle=none](\oenodeOut{7})(Det)
  \optdetector[detsize=0.6 0.6, fillstyle=solid,fillcolor=blue](\oenodeOut{6})(Det)
  \newpsstyle{Beam}{linewidth=1.5\pslinewidth}
  \drawbeam[linecolor=blue]{7-9}
  \addtopsstyle{Beam}{linecolor=red}
  \drawbeam(In){1-4}{6-8}
  \drawbeam{1}{5-8}
  \rput[r](\oenodeLabel{M}){$\tau$
    \psline[arrows=<->, arrowinset=0](0.15,0.25)(0.15,-0.15)}
\end{pspicture}
\end{LTXexample}

\begin{LTXexample}[pos=t, caption={caption}, label={ex:glan-thompson}]
\begin{pspicture}(-1,-0.5)(8,1.5)
  \newpsobject{perppol}{polarization}{poltype=perp, linecolor=green!90!black, polsize=1}
  \newpsobject{parallelpol}{polarization}{poltype=parallel, linecolor=red, polsize=0.8}
  \newpsstyle{Polarization}{arrowinset=0, arrowscale=1.2}
  \pnode(0,1){A}\pnode(8,1){B}\pnode(4,-0.5){C}
  \glanthompson[glanthompsongap=0.2, glanthompsonsize=2 1](A)(B)
  \optplane(B)\optplane[angle=90](C)
  \drawbeam(A){1-2}
  \drawbeam[linestyle=dashed, dash=2pt 2pt, linecolor=red, arrowscale=1.5, arrows=->](A){1}{3}
  \parallelpol[abspos=1](A)(B)
  \perppol[abspos=1](A)(B)
  \nodexn{(\oenodeBeam{})-1.5(!\oeBeamVec{})}{D}
  \perppol[abspos=7](A)(B)
  \parallelpol(D)(\oenodeBeam{})
\end{pspicture}
\end{LTXexample}

\enlargethispage{110pt}
\begingroup
\captionsetup[lstlisting]{format=poecaption}%
\begin{LTXexample}[pos=t, caption={\ifGERMAN Angepasst von \fi\ifENGLISH Adapted from \fi\doiurl{10.1364/OL.37.000930}}]
\begin{pspicture}(0,0.2)(13.5,4.7)
\psset[optexp]{optboxsize=1 0.8, usefiberstyle}
\pnode(1,3.2){Scan}\pnode([offset=-1.6]Scan){Sat}
\pnode([Xnodesep=5]Scan){ScanCpl}\pnode(ScanCpl|Sat){SatCpl}
\pnode([Xnodesep=1.5,offset=-0.8]ScanCpl){Cpl}\pnode([Xnodesep=5]Cpl){PD}
\pnode([Xnodesep=2.5, offset=-1.4]Cpl){Pump}\psset[optexp]{fiber=none}
\optbox[position=start, label=0](Scan)(ScanCpl){Scan}
\optmzm[abspos=1, compname=M1, extnode=t](Scan)(ScanCpl)
\optmzm[abspos=2.5, compname=M2, extnode=t](Scan)(ScanCpl)
\optamp[abspos=3.7](Scan)(ScanCpl)
\polcontrol[abspos=4.5, fiber=o](Scan)(ScanCpl)
\drawfiber{1}{2}{3}{4}{5}
\optbox[position=start, compname=S, extnode=b, label=0](Sat)(SatCpl){Sat}
\optmzm[abspos=1.75, compname=M3, extnode=b](Sat)(SatCpl)
\optamp[abspos=3.7](Sat)(SatCpl)
\polcontrol[abspos=4.5, fiber=o](Sat)(SatCpl)
\drawfiber{6}{7}{8}{9}
\wdmcoupler[fiber=i](ScanCpl)(SatCpl)(Cpl)
\optisolator[position=0.1](Cpl)(Pump|Cpl)
\optfiber[position=0.6](Cpl)(Pump|Cpl)
\addtopsstyle{OptCircArrow}{arrows=<-}
\optcirculator[optcircangle=0 -90](Cpl)(PD)(Pump)
\wdmsplitter[position=0.8, coupleralign=t](Cpl)(PD)
\optbox[position=end, label=0, compname=Pd, extnode=t](Cpl)(PD){PD}
\optbox[position=end, label=0, compshift=-1.5](Cpl)(PD){OSA}
\optamp[fiber](Pump)(\oenodeIfc{2}{13})
\optbox[position=start, optboxsize=0.6 1.2, label=0 . . absolute](Pump)(Pump|Cpl){Pump}
\drawfiber{10}{11}{12}{13}{14}{15}\drawfiber{14}{16}
% electrical stuff
\newpsstyle{Fiber}{}\psset[optexp]{label=0}
\optbox[compshift=0.7, optboxsize=2.5 0.8](\oenodeExt{M2})(\oenodeExt{Pd}|\oenodeExt{M2}){Lock-In Amp}
\ncangle[angleA=90, angleB=180, linearc=0.3]{\oenodeExt{M2}}{\oenodeIn{}}
\ncangle[angleB=90, linearc=0.3]{\oenodeOut{}}{\oenodeExt{Pd}}
\psset[optexp]{fiber=all, optboxsize=0.8 1, position=start}
\optbox(\oenodeExt{S}|Pump)(\oenodeExt{S}){\psline(-0.3,-0.2)(0.3,0.2)(0.3,-0.2)}
\optbox(\oenodeExt{M3}|Pump)(\oenodeExt{M3}){\psline(-0.3,-0.2)(0,0.2)(0.3,-0.2)}
\oscillator[output=none, unit=0.75, linewidth=0.666\pslinewidth]([offset=1]\oenodeExt{M1}){}{}
\psline(\oenodeExt{M1})([offset=0.4]\oenodeExt{M1})
\end{pspicture}
\end{LTXexample}
\endgroup

\enlargethispage{100pt}
\begingroup
\captionsetup[lstlisting]{format=poecaption}
\begin{LTXexample}[pos=t, caption={\ifENGLISH Adapted from \fi\ifGERMAN Angepasst von \fi\href{http://www.semibyte.de/wp/graphicslibrary/gl-physics/versuchsaufbauten-f-praktikum/}{semibyte.de}}, label={ex:absspektr}]
\begin{pspicture}(0.2,0.5)(9,7.4)
  \pnode(1,2){DL}\pnode([offset=0.5]DL){OAP}\pnode([Xnodesep=2]OAP){ST}
  \pnode([offset=-1.4]ST){SP4}\pnode([Xnodesep=4]SP4){SP3}
  \pnode([offset=3]SP3){JL}\pnode([Xnodesep=1]SP3|ST){SP1}
  \pnode([Xnodesep=1]ST|JL){SP2}\pnode([Xnodesep=1.5,offset=3]SP2){Det}
  \psset[optexp]{optboxsize=1.5 0.9, labeloffset=0.6}
  \begin{optexp}
    \optbox[position=start, innerlabel](DL)(OAP){\parbox{1.5\psunit}{\centering Dioden-\\laser}}
    \psset[optexp]{mirrortype=extended}
    \mirror[mirrorradius=2](DL)(OAP)(ST){OAP}
    \psset[optexp]{variable}
    \beamsplitter[bssize=0.4, labelangle=-45](SP4)(ST)(SP1){ST}
    \optplate[abspos=1, plateheight=0.7](ST)(SP1){CP}
    \mirror(ST)(SP1)(SP2){SP1}\mirror(SP1)(SP2)(Det){SP2}
    \optdipole[label=-0.7 . b relative, optdipolesize=2, position=0.6](SP2)(Det){%
      \psframe[dimen=outer](-1,-0.6)(1,0.6)
      \psset{fillstyle=solid, fillcolor=blue!40, linestyle=none}
      \psframe(-1,-0.5)(-0.9,0.5)\psframe(0.9,-0.5)(1,0.5)}{Plasmareaktor}
    \optdetector[label=. 30 l](SP2)(Det){Detektor}
    \optbox[position=end, innerlabel](SP3)(JL){\parbox{1.5\psunit}{\centering Justage-\\laser}}
    \mirror(SP4)(SP3)(JL){SP3}\mirror(ST)(SP4)(SP3){SP4}
    \psset{linewidth=2\pslinewidth}
    \drawbeam[linecolor=blue, beampos=0.03]{1-2}
    \drawbeam[beamalign=abs, loadbeampoints, linecolor=blue]{2-8}
    \drawbeam[linecolor=red, beampos=-0.03]{9-11}{3-8}
  \end{optexp}
  \pnode([Xnodesep=1.2,offset=-0.6]\oenodeIn{8}){NaCl}
  \psset{linestyle=dashed, arrows=->, arrowscale=1.5}
  \ncline[nodesepA=0.1, nodesepB=0.2]{NaCl}{\oenodeIn{7}}
  \ncline[nodesepA=0.1, nodesepB=0.3]{NaCl}{\oenodeOut{7}}
  \rput[l](NaCl){NaCl-Fenster}
\end{pspicture}
\end{LTXexample}
\endgroup

\begingroup
\captionsetup[lstlisting]{format=poecaption}
\begin{LTXexample}[pos=t, caption={\ifGERMAN Angepasst von \fi\ifENGLISH Adapted from \fi\doiurl{10.1364/AOP.1.000308}, \ifGERMAN Abb. \fi\ifENGLISH Fig. \fi 8}, label={ex:autocorrelation}]
\begin{pspicture}(5.7,2.8)
\psset{mirrorwidth=0.7, bsstyle=plate, bssize=0.5, arrowinset=0, arrowscale=1.2}
\newpsobject{splitterplate}{beamsplitter}{linewidth=2\pslinewidth, linecolor=gray!50}
\pnode(2.3,0){In}\pnode([offset=0.5]In){STM1}
\pnode([Xnodesep=-2]STM1){M1}\pnode([offset=1]M1){M2}
\pnode([offset=2]STM1){M3}\pnode([Xnodesep=-1]M3){M4}
\pnode(M4|M2){STM2}
\splitterplate(In)(STM1)(M1)
\mirror(STM1)(M1)(M2)
\mirror(M1)(M2)(M3|M2)
\mirror(STM1)(M3)(M4)
\mirror[label=0.6 180 . absolute](M3)(M4)(STM2)
\rput[r](\oenodeLabel{}){$\tau$
  \psline[arrows=<->](0.15, 0.4)(0.15, -0.2)}
\splitterplate[compoffset=0.2, compname=STM2](M4)(STM2)([Xnodesep=1]STM2)
\pnode(\oenodeCenter{STM2}){STM2C}
\pnode([Xnodesep=4]STM2C){Out}
\lens[n=2](STM2C)(Out)
\optbox[position=0.65, optboxsize=0.1 0.6](STM2C)(Out)
\optplate[linestyle=none, position=0.75](STM2C)(Out)
\pinhole[position=0.95, outerheight=0.6](STM2C)(Out)
\optdetector[detsize=0.5 0.6](STM2C)(Out)
\drawbeam[linecolor=blue]{8-}
\newpsstyle{Beam}{ArrowInside=->, linecolor=red, ArrowInsideMinLength=1, arrows=>-}
\drawbeam[ArrowInsidePos=0.835](In){1-3}{7-9}
\drawbeam[ArrowInsidePos=0.74](In){1}{4-9}
\end{pspicture}
\end{LTXexample}
\endgroup

\begin{LTXexample}[pos=t, linerange={1-1}, caption={caption}]

\psset{unit=1.1}
\begin{pspicture}(9.3,5.8)
  \psset{labeloffset=0.5, optboxsize=1 0.8, arrowscale=1.2, arrowinset=0}
  \newpsstyle{Fiber}{linecolor=red!70!black, linewidth=1.5\pslinewidth}
  \pnode(1, 3.4){LD}\pnode([Xnodesep=3.2]LD){LoopIn}\pnode([offset=-1]LoopIn){LoopInsIn}
  \pnode([offset=-1,Xnodesep=2]LoopIn){LoopInsOut}\pnode(LoopInsOut|LoopIn){LoopOut}
  \optswitch[compname=LSw, label=. 180 b, abspos=2.7, fiber=o](LD)(LoopIn){load switch}
  \optcoupler[addtoFiber={ArrowInside=->, ArrowInsidePos=0.7}](LoopIn)(LoopInsIn)(LoopOut)(LoopInsOut){50/50}
  \optbox[labelstyle=\footnotesize, position=end, fiber, label=0, optboxsize=1.4 1.2](LoopOut)([Xnodesep=0.1]LoopOut){\parbox{1.4\psxunit}{\centering Linear\\Optical\\Sampling}}%
  \pnode([Xnodesep=2.8]LoopInsOut){TR}
  \pnode([offset=-2]TR){BR}
  \pnode([Xnodesep=-1.5]LoopInsIn){TL}
  \pnode(TL|BR){BL}
  \psset[optexp]{fiber=none}
  \optisolator[isolatorsize=0.5, abspos=0.6](LoopInsOut)(TR){isolator}% 4
  \optbox[label=0, extnode=t, compname=PM, abspos=2](LoopInsOut)(TR){PM}
  \drawfiber(LoopInsOut){4}{5}
  \optfiber[label=0.2 . t, abspos=4](BL)(BR){fiber}
  \drawfiber[fiberstyle=bar, angleA=0, startnode=N, linearc=0.5, armA=0.6]{5}{6}
  \optamp[labelalign=b, abspos=3.8](BR)(BL){EDFA}
  \optfilter[label=. 180 b, usefiberstyle, abspos=1](BL)(BR){OBPF}
  \drawfiber{6}{7}{8}
  \optswitch[labelalign=t, abspos=1, fiber=o](TL)(LoopInsIn){unload switch}
  \drawfiber[angleA=180, linearc=0.5, armA=1, startnode=1, fiberstyle=bar]{8}{9}
  \optbox[extnode=t, compname=Mod, innerlabel, abspos=0.7](LD)(LoopIn){MOD}
  \optbox[position=start, innerlabel](LD)(LoopIn){LD}
  \drawfiber{}{Mod}
  \drawfiber[arrows=->]{Mod}{LSw}
  \psline[arrows=->]([offset=1]\oenodeExt{PM})(\oenodeExt{PM})
  \pnode([offset=1.2, Xnodesep=-1]\oenodeExt{Mod}){Osci}
  \oscillator[output=none, unit=0.8, linewidth=0.666\pslinewidth](Osci){}{}
  \uput{0.5}[90](Osci){SYN}
  \newpsstyle{Fiber}{}
  \optbox[compname=PG, extnode=b, abspos=0.6, fiber=i, label=0.5 180 b]([Xnodesep=0.4]Osci)(\oenodeExt{PM}|Osci){PG}
  \rput(\oenodeCenter{}){\psplot[plotpoints=200]{-0.3}{0.3}{2.7182818 x 0.05 div 2 exp neg exp 0.3 mul 0.15 sub}}
  \optfilter[label=0.5 180 b, abspos=1, fiber=i](\oenodeOut{PG})(\oenodeExt{PM}|Osci){BPF}
  \rput[r]([offset=0.4, Xnodesep=0.2]\oenodeOut{}){\psplot[plotpoints=200]{0}{1}{360 3.14159 div x 6 mul mul sin 2 exp 0.3 mul 0.15 sub}}
  \ncangle[angleA=-90, angleB=90, arrows=->, armB=0.5]{\oenodeExt{PG}}{\oenodeExt{Mod}}
  \ncangle[angleB=90, arrows=->]{\oenodeOut{}}{\oenodeExt{PM}}
  \rput([Xnodesep=0.1, offset=0.2]\oenodeOut{Mod}){%
    \psplot[plotpoints=200, unit=0.7]{0}{1}{2.7182818 x 0.5 sub 0.08 div 2 exp neg exp 0.5 mul}%
  }%
\end{pspicture}
\end{LTXexample}

\begingroup
\captionsetup[lstlisting]{format=poecaption}
\begin{LTXexample}[pos=t, linerange={1-1}, caption={\ifGERMAN Angepasst von \fi\ifENGLISH Adapted from \fi\doiurl{10.1364/OL.37.000797}}]

\begin{pspicture}(12.3,8.8)
\newpsobject{laser}{optbox}{position=start, innerlabel}
\psset[optexp]{lens=2, phwidth=0.07, outerheight=0.6}
\pnode(1,7){L}\pnode([offset=-6]L){PSLM}
\pnode([Xnodesep=2,offset=1]L){ASLM}\pnode([offset=-0.5,Xnodesep=9]L){MRef}
\pnode([offset=-7]ASLM){ML}\pnode([Xnodesep=8.5]ML){Cam}
\begin{optexp}
  \laser[optboxsize=1.6 0.6](L)(PSLM){Nd:YAG}
  \beamsplitter[bssize=0.4, labelangle=-90](L)(L|MRef)(MRef){BS}
  \lens[abspos=1.2, lens=0.5 0.5 0.4, n=2.5, labelangle=-10](L)(PSLM){MO}
  \pinhole[abspos=1.4, labelangle=10](L)(PSLM){PH}
  \lens[abspos=2.3](L)(PSLM){L}
  \opttripole[label=0.5](L)(PSLM)(ASLM){\psframe[dimen=outer](-0.5,0)(0.5,0.1)}{PSLM}
  \lens[label=0.6 -40](PSLM)(ASLM){L}
  \opttripole[label=0.5](PSLM)(ASLM)(ML){\psframe[dimen=outer](-0.5,0)(0.5,0.1)}{ASLM}
  \lens[position=0.45, labelangle=180](ASLM)(ML){L}
  \optretplate[labelangle=180, position=0.55](ASLM)(ML){$\lambda/2$}
  \optplate[labelangle=180, position=0.62](ASLM)(ML){P}
  \mirror[labeloffset=0.4](ASLM)(ML)(Cam){M}
  \newpsstyle{Beam}{fillcolor=green!80!black, opacity=0.5, fillstyle=solid, linestyle=none, beaminside=false}
  \drawwidebeam[beamwidth=0.1, stopinside]{1-5}
  \psset{loadbeampoints}
  \drawwidebeam[stopinside, savebeampoints=2]{5-7}
  \drawwidebeam[loadbeampoints=2, beamdiv=-8.5]{7-8}
  \drawwidebeam[loadbeampoints=2, beamdiv=-8.5, beamangle=-4]{7-8}
  \drawwidebeam[beamdiv=-8.5, beamangle=-4.5]{8-9}
  \drawwidebeam[loadbeampoints=2, beamdiv=-8.5, beamangle=4]{7-8}
  \drawwidebeam[beamdiv=-8.5, beamangle=4.5]{8-9}
  \lens[abspos=2](ML)(Cam){L}
  \lens[abspos=4](ML)(Cam){L}
  \crystal[abspos=6, voltage, crystalsize=1 0.6, fillcolor=yellow!90!black, fillstyle=solid](ML)(Cam){SBN}
  \beamsplitter[bssize=0.6](MRef)(MRef|Cam)(Cam){BS}
  \lens[n=2.4](MRef|Cam)(Cam){L}
  \optbox[optboxsize=0.8 0.6, position=end](ML)(Cam){Cam}
  \drawwidebeam[savebeampoints=2, stopinside]{9-13}
  \drawwidebeam[loadbeampoints=2, beamdiv=-16, beamangle=5, stopinside]{13-14}
  \drawwidebeam[beamangle=-5]{14-18}
  \drawwidebeam[loadbeampoints=2, beamdiv=-16, beamangle=-5, stopinside]{13-14}
  \drawwidebeam[beamangle=5]{14-18}
  \lens[lens=0.5 0.5 0.4, n=2](L|MRef)(MRef){MO}
  \pinhole[position=0.53, labelangle=180](L|MRef)(MRef){PH}
  \lens[position=0.65](L|MRef)(MRef){L}
  \optplate[position=0.7](L|MRef)(MRef){S}
  \mirror[labeloffset=0.4](L|MRef)(MRef)(MRef|Cam){M}
  \addtopsstyle{Beam}{fillcolor=red!70}
  \drawwidebeam[loadbeampoints=false, beamwidth=0.1, savebeampoints]{2}{19-21}
  \drawwidebeam{21-23}{16-18}
\end{optexp}
\end{pspicture}
\end{LTXexample}
\endgroup

\begingroup
\captionsetup[lstlisting]{format=poecaption}
\begin{LTXexample}[pos=t, linerange={1-1}, caption={\ifGERMAN Angepasst von \fi\ifENGLISH Adapted from \fi\doiurl{10.1364/AOP.1.000308}, \ifGERMAN Abb. \fi\ifENGLISH Fig. \fi 37}]

\begin{pspicture}(-2,-0.2)(8.3,5.9)
  \scriptsize
  \definecolor[ps]{bl}{rgb}{tx@addDict begin Red Green Blue end}%
  \addtopsstyle{SemitransMirror}{linestyle=solid, linewidth=0.7\pslinewidth}
  \newpsstyle{ExtendedMirror}{style=SemitransMirror}
  \psset[optexp]{mirrortype=extended, mirrorwidth=0.7, n=1, gratingalign=c}
  \newpsstyle{Beam}{linecolor=red!80!black, linewidth=1.5\pslinewidth, beaminside=false}
  \pnode(-2,0.5){In}\pnode(8,0.5){G1}\pnode([Xnodesep=-1.5, offset=1.3]G1){G2}\pnode(G1|G2){MG}
  \pnode([Xnodesep=1,offset=1]In){M1}
  \pnode([Xnodesep=5]In){M}
  \begin{optexp}
  \mirror[mirrortype=semitrans, mirrorlinewidth=0.7\pslinewidth, label=0.6 -90, compname=Et](In)([Xnodesep=-3]G1)(M1){Etalon}
  \optgrating[angle=40](In)(G1)(G2)
  \optgrating[reverse, angle=40](G1)(G2)(MG)
  \mirror[mirrorwidth=1, label=1 135](G2)(MG)(G2){Stretcher}
  \multido{\i=0+1}{40}{%
    \pstVerb{%
      \i\space 650 400 sub 39 div mul 400 add 
      tx@addDict begin wavelengthToRGB end }%
      \drawbeam[linecolor=bl, beamangle=\i\space 16 sub 0.2 mul]{2-3}%
      \drawbeam[linecolor=bl, loadbeampoints]{3-4}
  }%
  \newpsstyle{Beam}{fillstyle=solid, fillcolor=red!90!black, beamwidth=0.1, linestyle=none}
  \drawwidebeam(In){1-2}
  \pnode([offset=4]M1){M2}\pnode([Xnodesep=3]M2){M3}
  \pnode([offset=0.2,Xnodesep=0.2]M|M1){M4}
  \pnode([Xnodesep=4, offset=4]M){CM}
  \pnode([Xnodesep=-1,offset=-2]M3){SM}
  \pnode([offset=0.5]SM){S}
  \mirror[compname=M1](\oenodeIn{Et})(M1)(M2)
  \mirror(M1)(M2)(M3)
  \mirror(M2)(M3)(M4)
  \mirror[compname=M4, angle=1.5](M3)(M4)(CM)
  \mirror[mirrorradius=3.5 0, angle=2, compname=CM](M4)(CM)(SM)
  \mirror(G1)(M)(CM)
  \optretplate[plateheight=0.5, abspos=1.5, label=0.6](M)(CM){$\lambda/2$}
  \optbox[optboxsize=0.3 0.5, position=0.25, fillstyle=solid, fillcolor=yellow!90!black](CM)(SM){\begin{tabular}{@{}c@{}}nonlinear\\crystal\end{tabular}}
  \pinhole[phwidth=0.1, position=0.35](CM)(SM)
  \lens[lens=0.7 0.7 0.7, position=0.5, n=1.25](CM)(SM)
  \lens[lens=0.7 0.7 0.7, position=0.9, n=1.31](CM)(SM)
  \mirror[compname=SM](CM)(SM)(S)
  \optbox[position=end, optboxsize=0.8 1.9, compshift=0.6, label=0](SM)(S){Spectrometer}
  \drawwidebeam{Et}{5-8}\backlayer{\pnode(\oenodeBeamLow{}){BeamA}}
  \drawwidebeam[loadbeam]{8-9}\backlayer{\pnode(\oenodeBeamUp{}){BeamB}}
  \drawwidebeam[loadbeam]{9}{12-13}
  \drawwidebeam[beamangle=-1.9, beaminsidelast]{10-11}\backlayer{\pnode(\oenodeBeamLow{}){BeamC}}
  \drawwidebeam[loadbeam]{11}{9}\backlayer{\pnode(\oenodeBeamLow{}){BeamD}}
  \drawwidebeam[loadbeam]{9}{12-13}
  \addtopsstyle{Beam}{fillcolor=blue!40}
  \drawwidebeam[beamwidth=0, beamdiv=8, stopinside]{12-14}\backlayer{\pnode(\oenodeBeamUp{}){BeamE}}
  \drawwidebeam[loadbeam]{14-15}\backlayer{\pnode(\oenodeBeamUp{}){BeamF}}
  \drawwidebeam[loadbeam, startinside]{15-17}
  \end{optexp}
  % now put the pulses
  \def\mypulse{\psplot[style=Pulse]{-0.3}{0.3}{2.7182818 x 0.1 div 2 exp neg exp 0.8 mul}}%
  \newpsstyle{Pulse}{linecolor=red!90!black, linewidth=1.5\pslinewidth, plotpoints=200}
  \newpsstyle{Arrow}{arrowinset=0, arrowscale=1.2, linewidth=2\pslinewidth, linecolor=red!90!black}
  \rput([Xnodesep=0.3,offset=0.1]In){%
    \mypulse\psline[arrows=->, style=Arrow](0.3,0.2)(1,0.2)}%
  \rput([Xnodesep=1.5,offset=-0.3]\oenodeCenter{Et}){\psline[arrows=<->, style=Arrow](-0.7,0)(0.7,0)}
  \nlput[nrot=:U](\oenodeIn{M1})(\oenodeIn{Et}){2}{%
    \psline[arrows=->, style=Arrow](-0.3,0.25)(-1,0.25)%
    \rput(0,0.1){\psset{unit=0.7}\mypulse\rput(0.8,0){\mypulse}}}%
  \nlput[nrot=:U](BeamA)(BeamB){1}{%
    \psline[arrows=->, style=Arrow](1,0.25)(1.7,0.25)%
    \rput(0,0.05){\psset{unit=0.7}\mypulse\rput(0.8,0){\mypulse}}}%
  \nlput[nrot=:U](BeamD)(BeamC){2}{%
    \psline[arrows=->, style=Arrow](-1,0.25)(-1.7,0.25)%
    \psplot[style=Pulse]{-1}{1}{2.7182818 x 1 div 2 exp neg exp 0.5 mul 0.1 sub}}%
  \nlput[nrot=:U](BeamF)(BeamE){1.9}{%
    \rput(0,0.05){\addtopsstyle{Pulse}{linecolor=blue!50!red!50}\mypulse
    \rput(-0.7,0){\addtopsstyle{Pulse}{linecolor=blue!50}\mypulse}}}%
\end{pspicture}
\end{LTXexample}
\endgroup
% \iffalse
%</ignore>
% \fi
%
% 
% \ifGERMAN\chapter{Zusatzinformationen}\fi
% \ifENGLISH\chapter{Additional information}\fi
%
% \ifENGLISH\section{Internal component structure}\fi
% \ifGERMAN\section{Interne Struktur der Komponenten}\fi
% 
% \begin{optionlist}
% \boolitem[false]{showifcnodes}
% \styleitem[dotstyle=x, dotscale=1.5, linecolor=blue]{IfcNodeStyle}
% \end{optionlist}
%
% \ifENGLISH
% Every component consists internally of interfaces which are defined by a node
% on the optical axis, a plane vector or a curvature radius, and by its optical
% characteristics (reflective or transmittive, or both e.g. for
% \Lcs{beamsplitter}). The interface nodes can be visualized for each component
% with the \Lkeyword{showifcnodes} parameter.
% \fi
% \ifGERMAN
% Jede Komponente besteht aus Grenzflächen, die über einen Knoten auf der
% optischen Achse, einen Ebenevektor bzw. einen Krümmungsradius, und ihre
% optische Eigenschaft (reflektiv oder transmittiv, oder beides für
% z.B. \Lcs{beamsplitter}) definiert ist. Die Grenzflächenknoten können mit
% \Lkeyword{showifcnodes} angezeigt werden.
% \fi
% 
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(4,3)
  \psset{showifcnodes}
  \optbox(0,2.5)(4,2.5)
  \doveprism(0,1.5)(4,1.5)
  \lens(0,0.5)(4,0.5)
  \mirror(0,0.5)(3.5,0.5)(3.5,3)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \medskip
%
% \ifENGLISH 
% \nxLcs{draw*beam}\xLcs{drawbeam}\xLcs{drawwidebeam} calculates the distance
% between the interface nodes of two components and connects the two nearest
% to each other.
% \fi
% \ifGERMAN
% \nxLcs{draw*beam}\xLcs{drawbeam}\xLcs{drawwidebeam} berechnet den Abstand
% zwischen den Grenzflächenknoten zweier Komponenten und verbindet die beiden
% nächstgelegenen. 
% \fi
% 
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(-3,-3)(3,3)
  \psset{optboxsize=0.6 0.5, labeloffset=0}
  \multido{\i=0+60,\ii=1+1}{6}{%
    \pnode(2.5;\i){A}
    \optbox([Xnodesep=-1]A)([Xnodesep=1]A){\ii}
  }
  \optbox[compname=ref](-1,0)(1,0){ref}
  \addtopsstyle{Beam}{arrows=->}
  \multido{\i=1+1}{6}{\drawbeam{ref}{\i}}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifENGLISH\section{Overview of special nodes}\fi
% \ifGERMAN\section{Übersicht der Spezialknoten}\fi
%
% \ifENGLISH In this section you find overviews of all special nodes which
% each component provides. The possible positions for external and rotation
% reference nodes, and the interface nodes.
% \fi
% \ifGERMAN
% In diesem Abschnitt finden sie Übersichten für alle Spezialknoten, die von
% allen Komponenten bereitgestellt werden: die möglichen Positionen für externe
% und Rotationsknoten, und die Grenzflächenknoten.
% \fi
%
% \ifENGLISH\subsection{External and rotation reference nodes}\fi
% \ifGERMAN\subsection{Externe und Rotationsreferenzknoten}\fi
% \label{sec:overview-extnode}
%
% \ifENGLISH
% Here, you find all possible external (\prettyref{sec:extnode}) and rotation
% reference nodes (\prettyref{sec:rotrefnode}) for all components. Displayed are
% all possible combinations of \opt{t}, \opt{c}, or \opt{b} with \opt{l},
% \opt{c}, or \opt{r}. Not all components support all combinations, e.g. a plain
% \Lcs{mirror} ignores \opt{t} and \opt{b} and an \Lcs{optplate} ignores \opt{l}
% and \opt{r}.
%
% Instead of these values also fractional parts can be used: \opt{t} corresponds
% to $+1\cdot\Delta y$, \opt{b} corresponds to $-1\cdot\Delta y$, \opt{l}
% corresponds to $-1\cdot\Delta x$, and \opt{r} corresponds to $+1\cdot\Delta
% x$. In the following example the point $(0.5\Delta x, 1.2\Delta y)$ is
% provided as external node.
% \fi
% \ifGERMAN
% Hier finden Sie eine Übersicht über alle möglichen externen Knoten
% (\prettyref{sec:extnode}) und Rotationsknoten (\prettyref{sec:rotrefnode})
% aller Komponenten. Angezeigt werden die Positionen für alle möglichen
% Kombinationen von \opt{t}, \opt{c} oder \opt{b} mit \opt{l}, \opt{c} oder
% \opt{r}. Es sind nicht immer alle Möglichkeiten vorhanden, so können \opt{t}
% und \opt{b} ignoriert werden (z.B. bei \Lcs{mirror}), oder auch \opt{r} und
% \opt{l} (z.B. bei \Lcs{optplate}).
% 
% Anstelle dieser Werte können auch Bruchteile davon verwendet werden: \opt{t}
% entspricht $+1\cdot\Delta y$, \opt{b} entspricht $-1\cdot\Delta y$, \opt{l}
% entspricht $-1\cdot\Delta x$ und \opt{r} entspricht $+1\cdot\Delta x$. Im
% folgenden Beispiel wird der Punkt $(0.5\Delta x, 1.2\Delta y)$ als externer
% Knoten bereitgestellt.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]extnode}]
\begin{pspicture}(3,1)
  \optbox[extnode={0.5,1.2}, beam](0,0.5)(3,0.5)
  \psdot(\oenodeExt{})
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \newpsstyle{ExtNodeStyle}{dotstyle=B+, dotangle=45, linewidth=2\pslinewidth, linecolor=DOrange}
% \makeatletter
% \newcommand{\testextnodes}[3][]{%
%   \begin{pspicture}(3,2)
%   \@nameuse{#2}[#1]#3
%   \rput[t](1.5,0.9){\ttfamily\small
%     \ifx\\#1\\\relax
%     \begin{tabular}{@{}c@{}}\textbackslash #2\end{tabular}
%     \else\begin{tabular}{@{}c@{}}\textbackslash #2\\ #1\end{tabular}\fi}
%   \POE@extnodes[style=ExtNodeStyle,#1]{#2}
%   \end{pspicture}
% }%
% \makeatother
%
% \ifENGLISH\subsubsection*{Free-ray components}\fi
% \ifGERMAN\subsubsection*{Freistrahlkomponenten}\fi
%
% \testextnodes{lens}{(0,1.5)(3,1.5)}
% \testextnodes[lensradius=-1]{lens}{(0,1.5)(3,1.5)}
% \testextnodes{optplate}{(0,1.5)(3,1.5)}
% \testextnodes{optretplate}{(0,1.5)(3,1.5)}
% \testextnodes[phwidth=0.2]{pinhole}{(0,1.5)(3,1.5)}
% \testextnodes{optbox}{(0,1.5)(3,1.5)}
% \testextnodes{crystal}{(0,1.5)(3,1.5)}
% \testextnodes{optdetector}{(0,1.5)(2,1.5)}
% \testextnodes[dettype=diode]{optdetector}{(0,1.5)(2,1.5)}
% \testextnodes{optdiode}{(0,1.5)(3,1.5)}
% \testextnodes{doveprism}{(0,1.5)(3,1.5)}
% \testextnodes[glanthompsongap=0.15]{glanthompson}{(0,1.5)(3,1.5)}
% \bgroup
% \addtopsstyle{PiezoMirror}{unit=1.5}
% \testextnodes[mirrortype=piezo]{mirror}{(0,1.5)(2,1.5)(2,0)}
% \egroup
% \bgroup\psset{mirrordepth=0.25}
% \testextnodes[mirrortype=extended]{mirror}{(0,1.5)(2,1.5)(2,0)}
% \testextnodes{mirror}{(0,1.5)(2,1.5)(2,0)}
% \testextnodes[mirrortype=semitrans]{mirror}{(0,1.5)(2,1.5)(2,0)}
% \egroup
% \testextnodes{optprism}{(0,1.5)(1.5,1.5)(3,1)}
% \testextnodes{optgrating}{(0,1.5)(2,1.5)(2,0)}
% \testextnodes{beamsplitter}{(0,1.5)(2,1.5)(2,0)}
% \testextnodes[bsstyle=plate]{beamsplitter}{(0,1.5)(2,1.5)(2,0)}
% \testextnodes{rightangleprism}{(0,1.5)(2.5,1)(0,0.5)}
% \testextnodes{pentaprism}{(0,1.3)(2,1.3)(2,0)}
%
% \ifENGLISH\subsubsection*{Fiber components}\fi
% \ifGERMAN\subsubsection*{Faserkomponenten}\fi
%
% \testextnodes{optfiber}{(0,1)(3,1)}
% \testextnodes{optamp}{(0,1.5)(3,1.5)}
% \testextnodes{optmzm}{(0,1.5)(3,1.5)}
% \testextnodes{optfilter}{(0,1.5)(3,1.5)}
% \testextnodes{polcontrol}{(0,1.5)(3,1.5)}
% \testextnodes{optisolator}{(0,1.5)(3,1.5)}
% \testextnodes{optswitch}{(0,1.5)(3,1.5)}
% \testextnodes{fiberdelayline}{(0,1.5)(3,1.5)}
% \testextnodes{optfiberpolarizer}{(0,1.5)(3,1.5)}
% \testextnodes{fibercollimator}{(0,1.5)(3,1.5)}
% \testextnodes{optcirculator}{(0,1.6)(3,1.6)(1.5,0.9)}
% \testextnodes[couplersize=0.5 0.3]{optcoupler}{(0,2)(0,1)(3,2)(3,1)}
% \testextnodes{fiberbox}{(0,1.75)(0,1.25)(3,1.75)(3,1.25)}
%
%
% \ifENGLISH\subsection{Interface nodes}\fi
% \ifGERMAN\subsection{Grenzflächenknoten}\fi
% \label{sec:overview-ifcnode}
%
% \ifENGLISH
% Here, all available components and their interface nodes are listed. If
% a node is labeled as «1, N», it means that both nodes are equal.
% \fi
% \ifGERMAN Hier sind alle Komponenten und deren Grenzflächenknoten
% aufgelistet. Ist ein Knoten mit «1, N» beschriftet, dann fallen beide
% Knoten zusammen.
% \fi
%
% \ifENGLISH\subsubsection*{Free-ray components}\fi
% \ifGERMAN\subsubsection*{Freistrahlkomponenten}\fi
%
% \begingroup
% \addtopsstyle{Beam}{arrows=->, arrowinset=0, arrowscale=1.5}
% \newcommand{\showdipoleifc}[1]{%
%   \begin{pspicture}(0,-0.5)(3,1) 
%     \pnode(0,0.5){A}\pnode(3,0.5){B}
%     \csname #1\endcsname(A)(B)
%     \drawbeam(A){}(B)
%     \psdot(\oenodeIn{})\uput[-135](\oenodeIn{}){1}
%     \psdot(\oenodeOut{})\uput[-45](\oenodeOut{}){N}
%     \rput[bl](0,-0.4){\ttfamily\textbackslash #1}
%   \end{pspicture}
% }%
% \newcommand{\showdipoleoneifc}[1]{%
%   \begin{pspicture}(0,-0.5)(3,1) 
%     \pnode(0,0.5){A}\pnode(3,0.5){B}
%     \csname #1\endcsname(A)(B)
%     \drawbeam(A){}(B)
%     \psdot(\oenodeIn{})\uput[-135](\oenodeIn{}){1, N}
%     \rput[bl](0,-0.4){\ttfamily\textbackslash #1}
%   \end{pspicture}
% }%
% \showdipoleifc{lens}\hspace{\fill}%
% \showdipoleoneifc{optplate}\hspace{\fill}%
% \showdipoleifc{optretplate}%
% \bigskip
%
% \noindent\showdipoleoneifc{pinhole}\hspace{\fill}%
% \showdipoleifc{optbox}\hspace{\fill}%
% \showdipoleifc{crystal}
% \bigskip
%
% \noindent
% \begin{pspicture}(0, -0.5)(3,1)
%   \pnode(0,0.5){A}\pnode(2.5,0.5){B}
%   \optdetector(A)(B)
%   \drawbeam(A){}
%   \psdot(\oenodeIn{})\uput[-135](\oenodeIn{}){1, N}
%   \rput[bl](0,-0.4){\ttfamily\textbackslash optdetector}
% \end{pspicture}%
% \hspace{\fill}%
% \bgroup
% \addtopsstyle{Beam}{beaminside=false}%
% \showdipoleifc{optdiode}\egroup%
% \hspace{\fill}%
% \begin{pspicture}(0,-0.5)(3,1) 
%   \pnode(0,0.5){A}\pnode(3,0.5){B}
%   \doveprism(A)(B)
%   \drawbeam[raytrace=false](A){}(B)
%   \psdot(\oenodeIn{})\uput[135](\oenodeIn{}){1}
%   \psdot(\oenodeIfc{2}{})\uput[90](\oenodeIfc{2}{}){2}
%   \psdot(\oenodeOut{})\uput[45](\oenodeOut{}){N}
%   \rput[bl](0,-0.4){\ttfamily\textbackslash doveprism}
% \end{pspicture}%
%
% \begin{pspicture}(3,1.5)
%   \pnode(0,1){A}\pnode(2.5,1){B}\pnode(2.5,0){C}
%   \mirror(A)(B)(C)
%   \drawbeam(A){}(C)
%   \psdot(\oenodeIn{})\uput[-135](\oenodeIn{}){1, N}
%   \rput[bl](0,0){\ttfamily\textbackslash mirror}
% \end{pspicture}%
% \hspace{\fill}%
% \begin{pspicture}(3,1.5) 
%   \pnode(0,1){A}\pnode(1.5,1){B}\pnode(3,0){C}
%   \optprism(A)(B)(C)
%   \drawbeam[raytrace=false](A){}(C)
%   \psdot(\oenodeIn{})\uput[135](\oenodeIn{}){1}
%   \psdot(\oenodeOut{})\uput[45](\oenodeOut{}){N}
%   \rput[bl](0,0){\ttfamily\textbackslash optprism}
% \end{pspicture}%
% \hspace{\fill}% 
% \begin{pspicture}(3,1.5)
%   \pnode(0,1){A}\pnode(2.5,1){B}\pnode(2.5,0){C}
%   \optgrating(A)(B)(C)
%   \drawbeam(A){}(C)
%   \psdot(\oenodeIn{})\uput[-135](\oenodeIn{}){1, N}
%   \rput[bl](0,0){\ttfamily\textbackslash optgrating}
% \end{pspicture}%
%
% \begin{pspicture}(0,-0.5)(3,1.7) 
%   \pnode(0,0.7){A}\pnode(3,0.7){B}
%   \glanthompson[glanthompsonsize=1.8 1, glanthompsongap=0.2](A)(B)
%   \drawbeam(A){}(B)
%   \psdot(\oenodeIn{})\uput[135](\oenodeIn{}){1}
%   \psdot(\oenodeIfc{2}{})\uput[45](\oenodeIfc{2}{}){2}
%   \psdot(\oenodeIfc{3}{})\uput[30](\oenodeIfc{3}{}){3,C}
%   \psdot(\oenodeIfc{4}{})\uput[150](\oenodeIfc{4}{}){4}
%   \psdot(\oenodeOut{})\uput[45](\oenodeOut{}){N}
%   \rput[bl](0,-0.4){\ttfamily\textbackslash glanthompson}
% \end{pspicture}%
% \hspace{\fill}%
%
% \begin{pspicture}(3,2.5)
%   \pnode(0,1.5){A}\pnode(2.5,1.5){B}\pnode(2.5,0.4){C}
%   \beamsplitter[bssize=1.2](A)(B)(C)
%   \drawbeam(A){}(C)
%   \psdot(\oenodeIfc{1}{})\uput[135](\oenodeIfc{1}{}){1}
%   \psdot(\oenodeIfc{2}{})\uput[-45](\oenodeIfc{2}{}){2}
%   \psdot(\oenodeIfc{3}{})\uput[60](\oenodeIfc{3}{}){3,C}
%   \psdot(\oenodeIfc{4}{})\uput[0](\oenodeIfc{4}{}){4}
%   \psdot(\oenodeIfc{N}{})\uput[90](\oenodeIfc{N}{}){N}
%   \rput[bl](0,0){\ttfamily\textbackslash beamsplitter}
% \end{pspicture}%
% \hspace{\fill}%
% \begin{pspicture}(3,2.5)
%   \pnode(0,2){A}\pnode(2.5,1.5){B}\pnode(0,1){C}
%   \rightangleprism[raprismsize=2](A)(B)(C)
%   \drawbeam[arrows=->, arrowinset=0, arrowscale=1.5](A){}(C)
%   \psdot(\oenodeIn{})\uput[135](\oenodeIn{}){1}
%   \psdot(\oenodeIfc{2}{})\uput[45](\oenodeIfc{2}{}){2}
%   \psdot(\oenodeIfc{3}{})\uput[-45](\oenodeIfc{3}{}){3}
%   \psdot(\oenodeOut{})\uput[-135](\oenodeOut{}){N}
%   \rput[bl](0,0){\ttfamily\textbackslash rightangleprism}
% \end{pspicture}%
% \hspace{\fill}%
% \begin{pspicture}(3,2.5) 
%   \pnode(0,1.5){A}\pnode(2.1,1.5){B}\pnode(2.1,0.4){C}
%   \pentaprism[pentaprismsize=1](A)(B)(C)
%   \drawbeam[arrows=->, arrowinset=0, arrowscale=1.5](A){}(C)
%   \psdot(\oenodeIn{})\uput[135](\oenodeIn{}){1}
%   \psdot(\oenodeIfc{2}{})\uput[0](\oenodeIfc{2}{}){2}
%   \psdot(\oenodeIfc{3}{})\uput[90](\oenodeIfc{3}{}){3}
%   \psdot(\oenodeOut{})\uput[-45](\oenodeOut{}){N}
%   \rput[bl](0,0){\ttfamily\textbackslash pentaprism}
% \end{pspicture}%
% \endgroup
%
% \ifENGLISH\subsubsection*{Fiber components}\fi
% \ifGERMAN\subsubsection*{Faserkomponenten}\fi
%
% \newcommand{\showfdipoleifc}[1]{%
%   \begin{pspicture}(0,-0.5)(3,1) 
%     \pnode(0,0.5){A}\pnode(3,0.5){B}
%     \csname #1\endcsname(A)(B)
%     \psdot(\oenodeIn{})\uput[-135](\oenodeIn{}){1}
%     \psdot(\oenodeOut{})\uput[-45](\oenodeOut{}){N}
%     \rput[bl](0,-0.4){\ttfamily\textbackslash #1}
%   \end{pspicture}%
% }%
% \addtopsstyle{Fiber}{ArrowInside=->, ArrowInsidePos=0.6, arrowscale=1.5, arrowinset=0}
% \vspace*{5mm}%
% \showfdipoleifc{optfiber}\hspace{\fill}%
% \showfdipoleifc{optamp}\hspace{\fill}%
% \showfdipoleifc{optmzm}%
% \bigskip
%
% \noindent\showfdipoleifc{optfilter}\hspace{\fill}%
% \showfdipoleifc{polcontrol}\hspace{\fill}%
% \showfdipoleifc{optisolator}%
% \bigskip
%
% \noindent\showfdipoleifc{optswitch}\hspace{\fill}%
% \showfdipoleifc{fiberdelayline}\hspace{\fill}%
% \showfdipoleifc{optfiberpolarizer}%
% \bigskip
%
% \bgroup\psset{beam}
% \noindent\showfdipoleifc{fibercollimator}\egroup
% \hspace{\fill}%
% \begin{pspicture}(0,-0.5)(3,1.5)
%   \pnode(0,1){A}\pnode(3,1){B}\pnode(1.2,-0.1){C}
%   \optcirculator(A)(B)(C)
%   \psdot(\oenodeIn{})\uput[-135](\oenodeIn{}){1}
%   \psdot(\oenodeIfc{2}{})\uput[-45](\oenodeIfc{2}{}){2}
%   \psdot(\oenodeOut{})\uput[-45](\oenodeOut{}){N}
%   \rput[bl](0,-0.4){\ttfamily\textbackslash optcirculator}
% \end{pspicture}\hspace{\fill}%
% \begin{pspicture}(0,-0.5)(3,1.5)
%   \fiberbox[fiberboxcount=2x3](0,0.95)(0,0.45)(3,1.2)(3,0.2)
%   \psdot(\oenodeIn{})\uput[135](\oenodeIn{}){1}
%   \psdot(\oenodeIfc{2}{})\uput[-135](\oenodeIfc{2}{}){2}
%   \psdot(\oenodeIfc{3}{})\uput[45](\oenodeIfc{3}{}){3}
%   \psdot(\oenodeIfc{4}{})\uput[0](\oenodeIfc{4}{}){4}
%   \psdot(\oenodeOut{})\uput[-45](\oenodeOut{}){N}
%   \rput[bl](0,-0.4){\ttfamily\textbackslash fiberbox}
% \end{pspicture}
% \bigskip
%
% \noindent
% \begin{pspicture}(0,-0.5)(3,1.5)
%   \pnode(0,0.75){A}\pnode(3,1.5){B}\pnode(3,0){C}
%   \wdmsplitter[couplersize=0.5, couplersep=0.2](A)(B)(C)
%   \psdot(\oenodeIn{})\uput[135](\oenodeIn{}){1}
%   \psdot(\oenodeIfc{2}{})\uput[90](\oenodeIfc{2}{}){2}
%   \psdot(\oenodeOut{})\uput[-90](\oenodeOut{}){N}
%   \rput[bl](0,-0.4){\ttfamily\textbackslash wdmsplitter}
% \end{pspicture}%
% \hspace{\fill}%
% \begin{pspicture}(0,-0.5)(3,1.5)
%   \pnode(0,1.5){A}\pnode(0,0){B}\pnode(3,0.75){C}
%   \wdmcoupler[couplersize=0.5, couplersep=0.2](A)(B)(C)
%   \psdot(\oenodeIn{})\uput[90](\oenodeIn{}){1}
%   \psdot(\oenodeIfc{2}{})\uput[-90](\oenodeIfc{2}{}){2}
%   \psdot(\oenodeOut{})\uput[45](\oenodeOut{}){N}
%   \rput[bl](0,-0.4){\ttfamily\textbackslash wdmcoupler}
% \end{pspicture}%
% \hspace{\fill}%
% \begin{pspicture}(0,-0.5)(3,1.5)
%   \pnode(0,1.5){A}\pnode(0,0){B}\pnode(3,1.5){C}\pnode(3,0){D}
%   \optcoupler[couplersize=0.5, couplersep=0.2](A)(B)(C)(D)
%   \psdot(\oenodeIn{})\uput[90](\oenodeIn{}){1}
%   \psdot(\oenodeIfc{2}{})\uput[-90](\oenodeIfc{2}{}){2}
%   \psdot(\oenodeIfc{3}{})\uput[90](\oenodeIfc{3}{}){3}
%   \psdot(\oenodeOut{})\uput[-90](\oenodeOut{}){N}
%   \rput[bl](0,-0.4){\ttfamily\textbackslash optcoupler}
% \end{pspicture}%
%
%
% \ifGERMAN
%   \section{Abwärtskompatibilität}
% \fi
% \ifENGLISH
%   \section{Backward compatibility}
% \fi\label{sec:bwd-comp}
% 
% \ifENGLISH In this section you find a comprehensive listing of the behaviour
% which changed in a version compared to the previous one and which is not
% backward compatible. Here you find also information on what you must note when
% upgrading and how you must change old documents to work correctly with the
% newer version.
% \fi
% \ifGERMAN
% In diesem Abschnitt finden Sie eine umfangreiche Auflistung aller Änderungen
% in einer Version bezüglich der Vorgängerversion, die nicht abwärts kompatibel
% sind. Sie finden ebenfalls Informationen was Sie bei einem Wechsel zur neuen
% Version beachten müssen, und was sie bei älteren Dokumenten gegebenenfalls
% ändern müssen um mit der neuen Version korrekt zu funktionieren.  \fi
%
%
% \subsection{Version 3.3}\label{sec:bwd-comp-3.3}
%
% \begin{optionlist}
%   \poeitem{\textbackslash opttripole}
%   \ifGERMAN Der Ausgangswinkel für die Beschriftung des
%   \Lcs{opttripole} wurde um 180° geändert um konsistent zu den anderen
%   Dreipolen zu sein.
%   \fi
%   \ifENGLISH Changed the reference angle for the label of the
%   \Lcs{opttripole} to be consistent with the other tripoles.
%   \fi
% \end{optionlist}
%
% \ifGERMAN\subsubsection{Strahlknoten}\fi
% \ifENGLISH\subsubsection{Beam nodes}\fi
%
% \ifGERMAN Vor Version 3.3 sind the Strahlknoten \Lcs{oenodeBeamUp} und
% \Lcs{oenodeBeamLow} nicht korrekt ausgerichtet gewesen, «upper» und
% «lower» war immer relativ zur Strahlrichtung (analog zu
% \Lkeyword{extnodealign}\opt{=relative}).
%
% Das konnte zu Problemen führen wenn \Lkeyword{loadbeampoints} zusammen
% mit \Lkeyword{beamdiv} verwendet wurde, da das Vorzeichen von
% \Lkeyword{beamdiv} nicht eindeutig kontrahierenden bzw. expandierenden
% Strahlen zugeordnet war.
%
% Seit Version 3.3 werden die Strahlknoten analog zu
% \Lkeyword{extnodealign}\opt{=absolute} definiert und die Zuordnung
% eines negativen \Lkeyword{beamdiv} mit kontrahierenden Strahlen sowie
% positiven \Lkeyword{beamdiv} mit expandierenden Strahlen ist immer
% gültig. In den folgenden beiden Beispielen ist immer der
% \Lcs{oenodeBeamUp} gekennzeichnet.
% \fi
% \ifENGLISH Before version 3.3 the beam nodes 
% \Lcs{oenodeBeamUp} and \Lcs{oenodeBeamLow} were not swapped correctly
% and the orientation of «upper» and «lower» was only relative to the
% beam direction (equivalent to
% \Lkeyword{extnodealign}\opt{=relative}). 
%
% This could lead to problems when using \Lkeyword{loadbeampoints} with
% \Lkeyword{beamdiv}. In that case the sign of \Lkeyword{beamdiv} was
% not unambiguously associated with contracting or expanding beam.
% 
% As of version 3.3 the beam nodes are arranged according to
% \Lkeyword{extnodealign}\opt{=absolute} and the association of negative
% \Lkeyword{beamdiv} with a contracting and positive \Lkeyword{beamdiv}
% with an expanding beam is always valid. In the following two examples
% all \Lcs{oenodeBeamUp} are marked.
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(-2,-2)(2,2)
  \addtopsstyle{Beam}{fillstyle=solid, fillcolor=green!40}
  \multido{\i=0+90,\ia=1+2,\ib=2+2}{4}{%
    \optplate[position=end](0.3;\i)(1;\i)
    \optplate[position=end, plateheight=1.5](1;\i)(2;\i)
    \drawwidebeam[beamwidth=0.2](0.3;\i){\ia}
    \pnode(\oenodeBeamUp{}){Up}
    \drawwidebeam[loadbeampoints, beamdiv=45]{\ia-\ib}
    \psdot(Up)\psdot(\oenodeBeamUp{})
  }
\end{pspicture}
\end{LTXexample}

\begin{LTXexample}
\begin{pspicture}(-2,-2)(2,2)
  \addtopsstyle{Beam}{fillstyle=solid, fillcolor=green!40}
  \multido{\i=0+90,\ia=1+2,\ib=2+2}{4}{%
    \optplate[position=end](0.3;\i)(1;\i)
    \optplate[position=end](1;\i)(2;\i)
    \drawwidebeam[beamwidth=0.2](0.3;\i){\ia}
    \pnode(\oenodeBeamUp{}){Up}
    \drawwidebeam[loadbeampoints, beamdiv=-45]{\ia-\ib}
    \psdot(Up)\psdot(\oenodeBeamUp{})
  }
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \subsection{Version 3.0}\label{sec:bwd-comp-3.0}
%
% \ifENGLISH The changes in version 3.0 compared to version 2.1 which are not
% backward compatible.
% \fi
% \ifGERMAN Die Änderungen in Version 3.0 gegenüber Version 2.1, die nicht
% abwärtskompatibel sind.
% \fi
%
% \ifENGLISH\subsubsection{General parameters}\fi
% \ifGERMAN\subsubsection{Allgemeine Parameter}\fi
%
% \begin{optionlist}
%   \optitem*[new]{namingscheme}{old, new} 
%   \ifGERMAN
%   In Version 2.1 mussten spezielle Komponentenknoten über ihren expliziten
%   Namen angesprochen werden. Wenn Sie das alte Namensschema benötigen, da Sie
%   direkt auf die Knoten zugegriffen haben, so müssen Sie
%   \nxLkeyword{namingscheme=old} verwenden. Seit Version 3.0 werden Makros für
%   den Zugriff auf die Komponentenknoten bereitgestellt, so dass das
%   eigentlichen Namensschema unerheblich ist, siehe \prettyref{sec:objnodes}
%   \fi
%   \ifENGLISH
%   In version 2.1 special component nodes had to be accessed by their explicit
%   name. If you need the old naming scheme, because you accessed internal nodes
%   directly, then you must set \nxLkeyword{namingscheme=old}. Since version 3.0
%   explicit macros are provided to access all special component nodes, so that
%   the actual naming scheme does not matter, see \prettyref{sec:objnodes}.
%   \fi
%
%   \poeitem{\smash{\begin{tabular}[t]{@{}r@{}}endbox\\angle\\rotateref\end{tabular}}}
%   \ifENGLISH These options now affect all components.\fi
%   \ifGERMAN Diese Parameter wirken sich jetzt auf alle Komponenten aus.\fi
%   \vspace*{1cm}
%
%   \poeitem{extnode}
%   \ifENGLISH
%   Some components now provide more possible positions for
%   \Lkeyword{extnode}. \Lcs{optdetector} had only one possible external node,
%   which was accessible for any value of \Lkeyword{extnode}, now this node can
%   be accessed only with \Lkeyword{extnode}\opt{=r}. All other values give
%   different node positions.
%   \fi
%   \ifGERMAN 
%   Einigen Komponenten stellen nun mehr mögliche Positionen für
%   \Lkeyword{extnode} zur Verfügung. So muss war z.B. für \Lcs{optdetector} nur
%   ein Knoten möglich, der für jeden Wert von \Lkeyword{extnode} zugänglich
%   war, jetzt aber nur mit \Lkeyword{extnode}\opt{=r}. Alle anderen Werte
%   setzen den Knoten an andere Stellen.
%   \fi
%
%   \poeitem{\textbackslash optbox}
%   \ifENGLISH An \Lcs{optbox} does always have the input and output
%   nodes at the respective interfaces, whereas in version 2.1 the input
%   and output nodes where at the same position for
%   \Lkeyword{endbox}\opt{=true}.
%   \fi
%   \ifGERMAN Eine \Lcs{optbox} hat immer einen Eingangs- und
%   Ausgangsknoten an den entsprechenden Grenzflächen. In Version 2.1
%   fielen Eingangs- und Ausgangsknoten zusammen falls \Lkeyword{endbox}
%   auf \opt{true} gesetzt war.
%   \fi
%
%   \poeitem{\textbackslash fibercollimator}
%   \ifENGLISH The \Lcs{fibercollimator} has only a fiber connection by
%   default, the beam must be drawn manually or with \Lkeyword{beam}
%   option.
%   \fi
%   \ifGERMAN Der \Lcs{fibercollimator} hat in den Voreinstellungen nur
%   eine Faserverbindung, der Strahl muss manuell oder durch Angabe des
%   \Lkeyword{beam} Parameters gezeichnet werden.
%   \fi
% \end{optionlist}
%
% \ifENGLISH\subsubsection{Beam connections}\fi
% \ifGERMAN\subsubsection{Strahlverbindungen}\fi
%
% \ifENGLISH
% In version 2.1, beam connections could be internal, that is the connections
% were specified together with the compent (\Lkeyword{beam} or
% \Lkeyword{conn}), or external with an additional call of \Lcs{drawbeam}. The
% main reason for internal connections was the aesthetic aspect of drawing the
% beam behind the component, but also convenience played a role. Drawing the
% beam behind the component is possible with layering (\prettyref{sec:layers})
% since 3.0.
%
% Some of the variants of internal beam connections can be used also in 3.0:
% \fi
% \ifGERMAN
% In Version 2.1 konnten Strahlverbindungen intern sein, d.h. die Verbindung
% wurde zusammen mit der Komponenten definiert (z.B. mit \Lkeyword{beam}, oder
% \Lkeyword{conn}) oder extern über einen separaten Aufruf von \Lcs{drawbeam}.
% Der Hauptgrund für die internen Verbindungen war der ästhetische Aspekt,
% zuerst die Verbindung und dann die Komponente darüber zu zeichnen, aber
% Bequemlichkeit spielte auch eine Rolle. Seit Version 3.0 kann die Reihenfolge
% von Verbindungen und Komponenten über Ebenen geregelt werden
% (\prettyref{sec:layers}).
%
% Manche Varianten für interne Strahlverbindungen können auch in 3.0 verwendet
% werden:
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-3,5-5}]
\begin{pspicture}(3,2)
  \pnode(0,1){A}\pnode(3,1){B}
  \optbox[beam](A)(B)
  \rput[b]([offset=-0.9]\oenodeCenter{}){\ttfamily conn=o-i, conn=i-o}
\end{pspicture}
\end{LTXexample}

\begin{LTXexample}[linerange={1-3,5-5}]
\begin{pspicture}(3,2)
  \pnode(0,1){A}\pnode(3,1){B}
  \optbox[beam, beaminside=false](A)(B)
  \rput[b]([offset=-0.9]\oenodeCenter{}){\ttfamily conn=o-o}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifENGLISH
% Other internal connections need an additional \Lcs{drawbeam} call, and if you
% want to move the beam behind the component, the code must be wrapped in a
% \Lenv{optexp} environment. Except for this, external connection are equivalent:
% \fi
% \ifGERMAN
% Andere Verbindungen können nur über einen zusätzlichen \Lcs{drawbeam} Aufruf
% erreicht werden, falls die Verbindung dann hinter der Komponente sein soll,
% musst der beteiligte Code in eine \Lenv{optexp}-Umgebung geschachtelt
% werden. Außer diesem Aspekt sind die separaten Verbindungen äquivalent:
%\fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-4,6-6}]
\begin{pspicture}(3,2)
  \pnode(0,1){A}\pnode(3,1){B}
  \optbox(A)(B)
  \drawbeam(A){}
  \rput[b]([offset=-0.9]\oenodeCenter{}){\ttfamily conn=o-, conn=a-}
\end{pspicture}
\end{LTXexample}

\begin{LTXexample}[linerange={1-3,5-6}]
\begin{pspicture}(3,2)
  \pnode(0,1){A}\pnode(3,1){B}
  \optbox(A)(B)
  \rput[b]([offset=-0.9]\oenodeCenter{}){\ttfamily conn=-o, conn=-b}
  \drawbeam{}(B)
\end{pspicture}
\end{LTXexample}

\begin{LTXexample}[linerange={1-4,6-8}]
\begin{pspicture}(3,2)
  \pnode(0,1){A}\pnode(3,1){B}
  \begin{optexp}
    \optbox(A)(B)
    \rput[b]([offset=-0.9]\oenodeCenter{}){\ttfamily conn=i-, A-}
    \drawbeam[beaminsidelast](A){}
  \end{optexp}
\end{pspicture}
\end{LTXexample}

\begin{LTXexample}[linerange={1-4,6-8}]
\begin{pspicture}(3,2)
  \pnode(0,1){A}\pnode(3,1){B}
  \begin{optexp}
    \optbox(A)(B)
    \rput[b]([offset=-0.9]\oenodeCenter{}){\ttfamily conn=-i, conn=-B}
    \drawbeam[beaminsidefirst]{}(B)
  \end{optexp}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
%
% \makeatletter
% \bgroup
% \newcommand*{\index@preamble}{}
% \let\index@preamble=\relax
% \renewcommand{\setindexpreamble}[1]{\def\index@preamble{#1}}
% \renewcommand*{\idx@heading}{%
%   \twocolumn[\idx@@heading{\indexname}]%
%   \@mkboth{\indexname}{\indexname}%
% }
% \renewenvironment{theindex}{%
%   \if@twocolumn
%     \@restonecolfalse
%   \else
%     \@restonecoltrue
%   \fi
%   \columnseprule \z@
%   \columnsep 35\p@
%   \idx@heading%
%   \index@preamble\par\nobreak
%   \thispagestyle{\indexpagestyle}\parindent\z@
%   \setlength{\parskip}{\z@ \@plus .3\p@}%
%   \setlength{\parfillskip}{\z@ \@plus 1fil}%
%   \let\item\@idxitem
% }{%
%   \if@restonecol\onecolumn\else\clearpage\fi
% }
% \renewcommand*\@idxitem{\par\hangindent 40\p@}
% \renewcommand*\subitem{\@idxitem \hspace*{20\p@}}
% \renewcommand*\subsubitem{\@idxitem \hspace*{30\p@}}
% \renewcommand*\indexspace{%
%   \par \vskip 10\p@ \@plus5\p@ \@minus3\p@\relax
% }
% \renewcommand*\indexname{Index}
% \printindex[doc]
% \egroup
% \makeatother
%
% \appendix
%
% \ifGERMAN
% \chapter{Versionsgeschichte}
%
% Diese Versionsgeschichte ist eine Liste von Änderungen, die für den Nutzer des
% Pakets von Bedeutung sind. Änderungen, die eher technischer Natur sind und für
% den Nutzer des Pakets nicht relevant sind und das Verhalten des Pakets nicht
% ändern, werden nicht aufgeführt. Wenn ein Eintrag der Versionsgeschichte ein
% Feature als \emph{improved} oder \emph{extended} bekannt gibt, so bedeutet
% dies, dass eine Modifikation die Syntax und das Verhalten des Pakets nicht
% beeinflusst, oder das es für ältere Versionen kompatibel ist. Einträge, die
% als \emph{deprecated}, \emph{modified}, \emph{renamed}, oder \emph{removed}
% deklariert sind, verlangen besondere Aufmerksamkeit. Diese bedeuten, dass eine
% Modifikation Änderungen in existierenden Dokumenten mit sich ziehen kann. Die
% Zahlen an der rechten Seite stehen für die relevante Stelle dieser
% Dokumentation, zusätzliche Informationen zur Migration von älteren Dokumenten
% sind in \prettyref{sec:bwd-comp} zu finden.
% \fi
% \ifENGLISH
% \chapter{Revision history}
%
% This revision history is a list of changes relevant to users of this
% package. Changes of a more technical nature which do not affect the user
% interface or the behavior of the package are not included in the list. If an
% entry in the revision history states that a feature has been \emph{improved}
% or \emph{extended}, this indicates a modification which either does not affect
% the syntax and behavior of the package or is syntactically backwards
% compatible (such as the addition of an optional argument to an existing
% command). Entries stating that a feature has been \emph{deprecated},
% \emph{modified}, \emph{renamed}, or \emph{removed} demand attention. They
% indicate a modification which may require changes to existing documents. The
% numbers on the right indicate the relevant section of this manual, more
% information regarding backward compatibility can be found in
% \prettyref{sec:bwd-comp}.
% \fi
%
% \begin{changelog}
%\patchcmd{\release}{\setlength{\itemsep}{0pt}}{\setlength{\itemsep}{0pt}\setlength{\parsep}{0pt}}{}{}
%   \begin{release}{3.6}{2013-03-20}
%   \item Added option \opt{compoffset}\see{prm:compoffset}
%   \item Added option \opt{beampathskip}\see{prm:beampathskip}
%   \item Added option \opt{innercompalign}\see{prm:innercompalign}
%   \item Fixed some bugs in the raytracing and beam code.
%   \end{release}
%   \begin{release}{3.5}{2013-02-22}
%   \item Added option \opt{filterangle}\see{prm:filterangle}
%   \item Fixed wrong output fiber style in \cs{optcoupler}
%   \item Fixed strange Postscript error which occured with some
%     interpreters.
%   \end{release}
%   \begin{release}{3.4}{2013-02-03}
%   \item Fixed bugs when using \opt{fillstyle} for some components
%   \item Extended option \opt{switchsize}\see{cmd:optswitch}
%   \item Modified coupler center node to be on the base
%     line\see{sec:centernode}
%   \item Extended error checking for \cs{drawbeam} and
%     \cs{drawfiber}\see{sec:accessobj}
%   \item Fixed some bugs in the connection code
%   \end{release}
%   \begin{release}{3.3a}{2012-09-18}
%   \item Fixed bug which was exposed by an update of pst-node.
%   \item Fixed trailing spaces.
%   \end{release}
%   \begin{release}{3.3}{2012-08-17}
%   \item Extended \cs{opttripole} and \cs{optdipole}\see{cmd:optdipole}
%   \item Modified reference angle for label of
%     \cs{opttripole}\see{sec:bwd-comp-3.3}
%   \item Added option \opt{optdipolesize} to support two interfaces for
%     \cs{optdipole}\see{prm:optdipolesize}
%   \item Added option \opt{gratingalign}\see{prm:gratingalign}
%   \item Added option \opt{forcebeaminside}\see{prm:forcebeaminside}
%   \item Extended option \opt{mirrorradius}\see{prm:mirrorradius}
%   \item Improved \cs{drawbeam} and \cs{drawwidebeam} to be able to use
%     \opt{ArrowInside} without linestyle\see{prm:ArrowInsideMaxLength}
%   \item Fixed orientation of \cs{oenodeBeamUp} and
%     \cs{oenodeBeamLow}\see{cmd:oenodeBeamUp}
%   \item Fixed a bug related to \opt{beaminside} and ambiguous
%     components.
%   \item Fixed some trailing spaces
%   \item Added more examples\see{sec:examples}
%   \end{release}
%   \begin{release}{3.2}{2012-07-26}
%   \item Added component \cs{glanthompson}\see{cmd:glanthompson}
%   \item Added access to beam vectors with \cs{oeBeamVec},
%     \cs{oeBeamVecUp} and \cs{oeBeamVecLow}\see{cmd:oeBeamVec}
%   \item Fixed wrong computation of node distance in \cs{fiberbox}
%   \item Fixed bug in \cs{wdmsplitter} for \opt{coupleralign=b} and
%     \opt{couplertype=none}
%   \item Fixed bug when filling components placed with
%     \opt{position=end}/\opt{start}
%   \item Added value \opt{absolute} to parameter
%     \opt{labelref}\see{prm:labelref}
%   \item Added examples\see{sec:examples}
%   \end{release}
%   \begin{release}{3.1}{2012-07-17}
%   \item Added component \cs{fiberbox}\see{cmd:fiberbox}
%   \item Extended connection macros to not required curly braces around
%     node parenthesis any more\see{sec:namingobj}
%   \item Modified \cs{fibercollimator} to have
%     \opt{allowbeaminside=false} by default\see{cmd:fibercollimator}
%   \item Extended fiber couplers to allow using only two
%     nodes\see{sec:coupler}
%   \item Fixed a bug concerning node expressions with \cs{drawfiber}
%   \end{release}
%   \begin{release}{3.0}{2012-07-09}
%   \item Modified beam connections with \cs{drawbeam} to support
%     raytracing\see{cmd:drawbeam}
%   \item Added wide beams with \cs{drawwidebeam}\see{cmd:drawwidebeam}
%   \item Added \cs{drawfiber} for fiber connections\see{cmd:drawfiber}
%   \item Added \opt{optexp} environment for layering of components and
%     connections\see{sec:layers}
%   \item Added german documentation
%   \item Modified naming of component nodes\see{sec:objnodes}
%   \item Modified \opt{extnode} to work with more
%     components\see{prm:extnode}
%   \item Modified \opt{angle} and \opt{rotateref} to affect all
%     components\see{sec:rotshift}
%   \item Modified \opt{endbox} to affect all
%     components\see{sec:positioning}
%   \item Extended \opt{position} by values \opt{start} and
%     \opt{end}\see{sec:positioning}
%   \item Extended \opt{abspos} by values \opt{start} and
%     \opt{end}\see{sec:positioning}
%   \item Removed deprecated lens code which used \opt{lenswidth} and
%     \opt{lensheight} for construction\see{cmd:lens}
%   \item Added option \opt{platesize}\see{prm:platesize}
%   \item Added option \opt{phwidth}\see{cmd:pinhole}
%   \item Modified option \opt{caxislength}\see{cmd:crystal}
%   \item Deprecated option \opt{lampscale}\see{cmd:crystal}
%   \item Added style \opt{CrystalCaxis}\see{cmd:crystal}
%   \item Added style \opt{CrystalLamp}\see{cmd:crystal}
%   \item Added option \opt{optboxsize}\see{cmd:optbox}
%   \item Extended option \opt{detsize}\see{cmd:optdetector}
%   \item Added style \opt{DetectorStyle}\see{cmd:optdetector}
%   \item Removed deprecated \cs{detector}, use
%     \cs{optdetector}\see{cmd:optdetector}
%   \item Extended option \opt{doveprismsize}\see{cmd:doveprism}
%   \item Added style \opt{Polarization}\see{cmd:polarization}
%   \item Deprecated option \opt{pollinewidth}\see{cmd:polarization}
%   \item Removed option \opt{polwidth}\see{cmd:polarization}
%   \item Removed option \opt{pol}\see{cmd:polarization}
%   \item Added style \opt{VariableStyle}\see{cmd:mirror}
%   \item Added mirror type \opt{semitrans}\see{prm:mirrortype}
%   \item Renamed \cs{optgrid} to \cs{optgrating}\see{cmd:optgrating}
%   \item Renamed \opt{optgridwidth} to
%     \opt{gratingwidth}\see{cmd:optgrating}
%   \item Renamed \opt{optgridheight} to
%     \opt{gratingheight}\see{cmd:optgrating}
%   \item Renamed \opt{optgriddepth} to
%     \opt{gratingdepth}\see{cmd:optgrating}
%   \item Renamed \opt{optgridcount} to
%     \opt{gratingcount}\see{cmd:optgrating}
%   \item Renamed \opt{optgridtype} to
%     \opt{gratingtype}\see{cmd:optgrating}
%   \item Renamed \opt{optgridlinewidth} to
%     \opt{gratinglinewidth}\see{cmd:optgrating}
%   \item Added option \opt{prismalign}\see{cmd:optprism}
%   \item Modified faulty alignment of
%     \cs{rightangleprism}\see{cmd:rightangleprism}
%   \item Extended option \opt{optampsize}\see{cmd:optamp}
%   \item Extended option \opt{optmzmsize}\see{cmd:optmzm}
%   \item Added option \opt{polcontroltype}\see{cmd:polcontrol}
%   \item Extended option \opt{isolatorsize}\see{cmd:optisolator}
%   \item Added style \opt{IsolatorArrow}\see{cmd:optisolator}
%   \item Extended option \opt{fdlsize}\see{cmd:fiberdelayline}
%   \item Added style \opt{FdlArrow}\see{cmd:fiberdelayline}
%   \item Extended option \opt{fiberpolsize}\see{cmd:optfiberpolarizer}
%   \item Added component \cs{optcirculator}\see{cmd:optcirculator}
%   \item Extended option \opt{couplersize}\see{cmd:optcoupler}
%   \item Extended option \opt{couplertype}\see{cmd:optcoupler}
%   \item Renamed option \opt{align} to
%     \opt{coupleralign}\see{cmd:optcoupler}
%   \item Added style \opt{VariableCoupler}\see{cmd:optcoupler}
%   \item Added style \opt{FilterStyle}\see{cmd:optfilter}
%   \item Extended option \opt{fibercolsize}\see{cmd:fibercollimator}
%   \item Removed deprecated option \opt{labelrelative}\see{sec:labels}
%   \item Removed deprecated option \opt{iwidth}\see{cmd:pinhole}
%   \item Removed deprecated option \opt{owidth}\see{cmd:pinhole}
%   \item Removed deprecated option \opt{bswidth}\see{cmd:beamsplitter}
%   \item Deprecated \cs{newOptexpDipoleNolabel}, use
%     \cs{newOptexpDipole}\see{sec:newobj}
%   \item Deprecated option
%     \opt{refractiveindex}\see{prm:refractiveindex}
%   \item Deprecated option \opt{conn}\see{sec:drawbeam}
%   \item Extended option \opt{fiber}\see{prm:fiber}
%   \end{release}
%   \begin{release}{2.1}{2009-11-05}
%   \item Added component
%     \cs{optfiberpolarizer}\see{cmd:optfiberpolarizer}
%   \item Added option \opt{compshift}\see{prm:compshift}
%   \item Added option \opt{label}\see{prm:label}
%   \item Added option \opt{connjoin}
%   \item Added options \opt{addtoBeam} and
%     \opt{newBeam}\see{sec:drawbeam}
%   \item Added style \opt{OptComp} and related options
%     \opt{addtoOptComp} and \opt{newOptComp}\see{sec:appearance}
%   \item Added option \opt{bsstyle}\see{cmd:beamsplitter}
%   \item Extended \cs{fibercollimator} to use up to four reference
%     nodes\see{cmd:fibercollimator}
%   \item Improved \opt{thicklens} to work also with plain
%     lenses\see{prm:thicklens}
%   \item Use pst-doc class for the documentation
%   \end{release}
%
%   \begin{release}{2.0}{2008-07-27}
%   \item Added fiber-optical components\see{chap:fibercomp}
%   \item Added component \cs{optdiode}\see{cmd:optdiode}
%   \item Added component \cs{pentaprism}\see{cmd:pentaprism}
%   \item Added component \cs{rightangleprism}\see{cmd:rightangleprism}
%   \item Added component \cs{doveprism}\see{cmd:doveprism}
%   \item Added component \cs{optprism}\see{cmd:optprism}
%   \item Added \cs{drawbeam}\see{sec:drawbeam}
%   \item Added component connections (options \opt{fiber}, \opt{conn}
%     and \opt{beam})\see{chap:connecting}
%   \item Added option \opt{compname}\see{prm:compname}
%   \item Added option \opt{extnode}\see{prm:extnode}
%   \item Renamed \cs{detector} to \cs{optdetector}\see{cmd:optdetector}
%   \end{release}
%   \begin{release}{1.2}{2008-06-17}
%   \item Modified lens design to use interface curvatures\see{cmd:lens}
%   \item Added options \opt{lensradiusleft} and
%     \opt{lensradiusright}\see{cmd:lens}
%   \item Added option \opt{thicklens}\see{cmd:lens}
%   \item Added option \opt{lenstype}\see{cmd:lens}
%   \item Added option \opt{mirrorradius} (curved
%     mirrors)\see{cmd:mirror}
%   \item Added option \opt{optgridtype} (binary
%     gratings)\see{cmd:optgrating}
%   \item Added \cs{newOptexpDipole}\see{sec:newobj}
%   \item Added \cs{newOptexpDipoleNolabel}\see{sec:newobj}
%   \item Added \cs{newOptexpTripole}\see{sec:newobj}
%   \item Added \cs{newOptexpFiberDipole}\see{sec:newobj}
%   \item General improvements of \TeX{} and Postscript code
%   \end{release}
%   \begin{release}{1.1}{2007-09-06}
%   \item Improved labeling features\see{sec:labels}
%   \item Added parameter \opt{labelref}\see{sec:labels}
%   \item Replaced \opt{labelrelative} by
%     \opt{labelref=relative}\see{sec:labels}
%   \item Renamed \cs{polarisation} to
%     \cs{polarization}\see{cmd:polarization}
%   \item Renamed \opt{polwidth} to \opt{polsize}\see{cmd:polarization}
%   \item Renamed \opt{pol} to \opt{poltype}\see{cmd:polarization}
%   \item Renamed \opt{bswidth} to \opt{bssize}\see{cmd:beamsplitter}
%   \item Renamed \opt{iwidth} to \opt{innerheight}\see{cmd:pinhole}
%   \item Renamed \opt{owidth} to \opt{outerheight}\see{cmd:pinhole}
%   \item Added support for fillstyle for all components
%   \end{release}
%
%   \begin{release}{1.0}{2007-07-18}
%   \item First CTAN version
%   \end{release}
% \end{changelog}
%
% \StopEventually{}
%
%   \begin{otherlanguage}{english}
%    \printindex[idx]
%  \end{otherlanguage}
%
% \chapter{The \LaTeX/\TeX\ implementation}
%<*stylefile>
% \section{Requirements}
%    \begin{macrocode}
\RequirePackage{pstricks}
\RequirePackage{pst-xkey}
\RequirePackage{pst-node}
\RequirePackage{pst-plot}
\RequirePackage{multido}
\RequirePackage{pst-eucl}
\RequirePackage{pstricks-add}
\RequirePackage{environ}
%    \end{macrocode}
% Add the Postscript header file.
%    \begin{macrocode}
\@addtofilelist{pst-optexp.pro}{}%
\pst@addfams{optexp}
\pstheader{pst-optexp.pro}
%    \end{macrocode}
% This holds a comma-separated list of all component names which are defined in
% a \nxLenv{pspicture} environment. This list is cleared when leaving the
% \nxLenv{pspicture}.
%    \begin{macrocode}
\gdef\POE@complist{}%
\gdef\POE@beamlist{1}%
\g@addto@macro{\endpspicture}{%
%    \end{macrocode}
%
% Undefine all beam nodes at the end of the \nxLenv{pspicture}.
%    \begin{macrocode}
  \expandafter\XKV@for@n\expandafter{\POE@beamlist}\POE@temp{%
    \POE@Verb{%
      /lastBeamPointUp\POE@temp\space 
      /lastBeamPointLow\POE@temp\space 
      /lastBeamPoint\POE@temp\space 
      3 { currentdict exch undef } repeat 
      /N@\oenodeBeam{\POE@temp} 
      /N@\oenodeBeamUp{\POE@temp} 
      /N@\oenodeBeamLow{\POE@temp}
      3 { tx@NodeDict exch undef } repeat
    }%
  }%
%    \end{macrocode}
%
% Reset the component list.
%
%    \begin{macrocode}
  \gdef\POE@complist{}\gdef\POE@beamlist{1}\global\POE@cnt=0\relax
}%
%    \end{macrocode}
% Some convenience definitions.
%    \begin{macrocode}
\def\pst@optexpdict{tx@OptexpDict begin }
\def\POE@dict#1{\pst@optexpdict #1 end}
\SpecialCoor
%    \end{macrocode}
% \section{Basic definitions}
%
% \subsection{Switches for the boolean keys}
% See respective key definitions for explanation.
%    \begin{macrocode}
\newif\ifPOE@connjoin
\newif\ifPOE@backlayer
\newif\ifPOE@frontlayer
\newif\ifPOE@optexpenv
\newif\ifPOE@variable
\newif\ifPOE@voltage
\newif\ifPOE@caxisinv
\newif\ifPOE@reverse
\newif\ifPOE@lamp
\newif\ifPOE@component@optional
\newif\ifPOE@debug@showoptdots
\newif\ifPOE@debug@showifcnodes
\newif\ifPOE@endbox
\newif\ifPOE@startbox
\newif\ifPOE@thicklens
\newif\ifPOE@usefiberstyle
\newif\ifPOE@fiber@
\newif\ifPOE@nofiber@
\newif\ifPOE@fiberin@
\newif\ifPOE@fiberin@top
\newif\ifPOE@fiberin@bottom
\newif\ifPOE@fiberout@
\newif\ifPOE@fiberout@top
\newif\ifPOE@fiberout@bottom
\newif\ifPOE@fiberpreset@
\newif\ifPOE@nofiberpreset@
\newif\ifPOE@fiberpresetin@
\newif\ifPOE@fiberpresetin@top
\newif\ifPOE@fiberpresetin@bottom
\newif\ifPOE@fiberpresetout@
\newif\ifPOE@fiberpresetout@top
\newif\ifPOE@fiberpresetout@bottom
\newif\ifPOE@beam
\newif\ifPOE@startinside
\newif\ifPOE@stopinside
\newif\ifPOE@beaminsidefirst
\newif\ifPOE@beaminsidelast
\newif\ifPOE@savebeam
\newif\ifPOE@loadbeam
\newif\ifPOE@beaminside
\newif\ifPOE@raytrace
\newif\ifPOE@pswarning
\newif\ifPOE@useNA
%    \end{macrocode}
% This is to check if \nxLkeyword{compname} is set inside or outside of a component. For this no boolean key is provided.
%    \begin{macrocode}
\newif\ifPOE@insideobj\POE@insideobjfalse
%    \end{macrocode}
% \subsection{Counters}
% Count the components in one \nxLenv{pspicture} environment.
%    \begin{macrocode}
\newcount\POE@cnt
\newcount\POE@oldcnt
%    \end{macrocode}
% Count the temporal planes which are created for connections to nodes.
%    \begin{macrocode}
\newcount\POE@nodecnt
%    \end{macrocode}
%    \begin{macrocode}
\newdimen\POE@dim
%    \end{macrocode}
% \subsection{Fixed strings}
% These are all the fixed strings which are used as possible values for
% choicekeys.
%    \begin{macrocode}
\def\POE@str@pol@polperp{perp}
\def\POE@str@pol@polparallel{parallel}
\def\POE@str@pol@polmisc{misc}
\def\POE@str@pol@polrcirc{rcirc}
\def\POE@str@pol@pollcirc{lcirc}
\def\POE@str@mirrortype@piezo{piezo}
\def\POE@str@mirrortype@plain{plain}
\def\POE@str@mirrortype@extended{extended}
\def\POE@str@mirrortype@semitrans{semitrans}
\def\POE@str@gratingtype@blazed{blazed}
\def\POE@str@gratingtype@binary{binary}
\def\POE@str@relative{relative}
\def\POE@str@absolute{absolute}
\def\POE@str@labelref@relgrav{relgrav}
\def\POE@str@labelref@global{global}
\def\POE@str@filtertype@bandpass{bandpass}
\def\POE@str@filtertype@bandstop{bandstop}
\def\POE@str@filtertype@lowpass{lowpass}
\def\POE@str@filtertype@highpass{highpass}
\def\POE@str@couplertype@none{none}
\def\POE@str@couplertype@ellipse{ellipse}
\def\POE@str@couplertype@elliptic{elliptic}
\def\POE@str@couplertype@rectangle{rectangle}
\def\POE@str@couplertype@cross{cross}
\def\POE@str@polcontroltype@linear{linear}
\def\POE@str@polcontroltype@triangle{triangle}
\def\POE@str@top{top}
\def\POE@str@bottom{bottom}
\def\POE@str@center{center}
\def\POE@str@closed{closed}
\def\POE@str@opened{opened}
\def\POE@str@dettype@round{round}
\def\POE@str@dettype@diode{diode}
\def\POE@str@bsstyle@cube{cube}
\def\POE@str@bsstyle@plate{plate}
\def\POE@str@auto{auto}
\def\POE@str@center{center}
\def\POE@str@verbose{verbose}
\def\POE@str@quiet{quiet}
\def\POE@Verb#1{\pst@Verb{\pst@optexpdict #1 end }}%
%    \end{macrocode}
%
% \section{Parameter and style definitions}
% The parameters and styles are commented quiet well in the user documentation,
% here you will find only additional comments about technical peculiarities.
%    \begin{macrocode}
\newpsstyle{OptComp}{}%
\define@key[psset]{optexp}{newOptComp}{%
  \newpsstyle{OptComp}{#1}%
}
\define@key[psset]{optexp}{addtoOptComp}{%
  \addtopsstyle{OptComp}{#1}%
}
\newpsstyle{OptionalStyle}{linestyle=dashed,dash=1.5pt 1pt}%
\newpsstyle{IfcNodeStyle}{dotstyle=x, dotscale=1.5, linecolor=blue}%
\newpsstyle{Beam}{linecolor=green!90!black, linejoin=1}%
\define@key[psset]{optexp}{newBeam}{%
  \newpsstyle{Beam}{#1}%
}
\define@key[psset]{optexp}{addtoBeam}{%
  \addtopsstyle{Beam}{#1}%
}
%    \end{macrocode}
% Styles for the automatic fiber connections.
%    \begin{macrocode}
\newpsstyle{Fiber}{}%
\define@key[psset]{optexp}{newFiber}{%
  \newpsstyle{Fiber}{#1}%
}
\define@key[psset]{optexp}{addtoFiber}{%
  \addtopsstyle{Fiber}{#1}%
}
\newpsstyle{FiberIn}{style=Fiber}%
\define@key[psset]{optexp}{newFiberIn}{%
  \newpsstyle{FiberIn}{#1}%
}
\define@key[psset]{optexp}{addtoFiberIn}{%
  \addtopsstyle{FiberIn}{#1}%
}
\newpsstyle{FiberOut}{style=Fiber}%
\define@key[psset]{optexp}{newFiberOut}{%
  \newpsstyle{FiberOut}{#1}%
}
\define@key[psset]{optexp}{addtoFiberOut}{%
  \addtopsstyle{FiberOut}{#1}%
}
\newpsstyle{FiberIn1}{style=FiberIn}%
\define@key[psset]{optexp}{newFiberIn1}{%
  \newpsstyle{FiberIn1}{#1}%
}
\define@key[psset]{optexp}{addtoFiberIn1}{%
  \addtopsstyle{FiberIn1}{#1}%
}
\newpsstyle{FiberIn2}{style=FiberIn}%
\define@key[psset]{optexp}{newFiberIn2}{%
  \newpsstyle{FiberIn2}{#1}%
}
\define@key[psset]{optexp}{addtoFiberIn2}{%
  \addtopsstyle{FiberIn2}{#1}%
}
\newpsstyle{FiberOut1}{style=FiberOut}%
\define@key[psset]{optexp}{newFiberOut1}{%
  \newpsstyle{FiberOut1}{#1}%
}
\define@key[psset]{optexp}{addtoFiberOut1}{%
  \addtopsstyle{FiberOut1}{#1}%
}
\newpsstyle{FiberOut2}{style=FiberOut}%
\define@key[psset]{optexp}{newFiberOut2}{%
  \newpsstyle{FiberOut2}{#1}%
}
\define@key[psset]{optexp}{addtoFiberOut2}{%
  \addtopsstyle{FiberOut2}{#1}%
}
%    \end{macrocode}
% Special styles to change only a part of some devices.
%    \begin{macrocode}
\newpsstyle{ExtendedMirror}{%
  linestyle=none, hatchwidth=0.5\pslinewidth,
  hatchsep=1.4\pslinewidth, fillstyle=hlines
}%
\newpsstyle{VariableStyle}{%
  linewidth=0.8\pslinewidth, arrowinset=0, arrowscale=0.8, arrows=<->
}
\newpsstyle{SemitransMirror}{linestyle=none, fillstyle=solid,fillcolor=black!30}%
\newpsstyle{PiezoMirror}{fillstyle=solid,fillcolor=black!30}%
\newpsstyle{IsolatorArrow}{linewidth=2\pslinewidth, arrowinset=0}
\newpsstyle{CrystalCaxis}{%
  linestyle=dashed, dash=2pt 2pt, linewidth=0.7\pslinewidth, 
  arrowinset=0, arrows=->
}
\newpsstyle{CrystalLamp}{linewidth=0.6\pslinewidth}
\newpsstyle{FdlArrow}{arrowinset=0, arrows=->}
\newpsstyle{VariableCoupler}{arrowinset=0, arrows=->}
%    \end{macrocode}
%
% \subsection{General parameters}
%    \begin{macrocode}
\define@boolkey[psset]{optexp}[POE@component@]{optional}[true]{}
\define@boolkey[psset]{optexp}[POE@]{usefiberstyle}[true]{}
\define@boolkey[psset]{optexp}[POE@debug@]{showoptdots}[true]{}
\define@boolkey[psset]{optexp}[POE@debug@]{showifcnodes}[true]{}
%    \end{macrocode}
% The positioning parameters.
%    \begin{macrocode}
\define@boolkey[psset]{optexp}[POE@]{endbox}[true]{}
\define@boolkey[psset]{optexp}[POE@]{startbox}[true]{}
\define@choicekey*+[psset]{optexp}{position}[\val\nr]{start,end}{%
  \ifcase\nr\relax
    \psset[optexp]{startbox, endbox=false}%
  \or
    \psset[optexp]{startbox=false, endbox=true}%
  \fi
}{%
  \psset[optexp]{startbox=false, endbox=false}%
  \edef\POE@key@position{#1}%
}%
\define@choicekey*+[psset]{optexp}{abspos}[\val\nr]{start,end}{%
  \ifcase\nr\relax
    \psset[optexp]{startbox, endbox=false}%
  \or
    \psset[optexp]{startbox=false, endbox=true}%
  \fi
}{%
  \psset[optexp]{startbox=false, endbox=false}%
  \edef\POE@key@abspos{#1}%
}%
\define@key[psset]{optexp}{compshift}{%
  \pst@checknum{#1}\POE@key@compshift
}
\define@key[psset]{optexp}{angle}{%
  \pst@checknum{#1}\POE@key@angle
}
\define@key[psset]{optexp}{compoffset}{%
  \pst@checknum{#1}\POE@key@compoffset
}
\define@choicekey+[psset]{optexp}{innercompalign}%
  [\val\nr]{rel,abs,relative,absolute}%
  {%
    \ifcase\nr\relax
      \let\POE@key@innercompalign\POE@str@relative
    \or
      \let\POE@key@innercompalign\POE@str@absolute
    \else
      \def\POE@key@innercompalign{#1}%
    \fi
  }%
  {\PackageError{pst-optexp}{Unknown value '\val' for innercompalign}}%
\psset[optexp]{%
  position={},
  abspos={},
  compshift=0,
  compoffset=0,
  innercompalign=relative,
  angle=0
}%
%    \end{macrocode}
% Layering
%    \begin{macrocode}
\define@boolkey[psset]{optexp}[POE@]{backlayer}[true]{}
\define@boolkey[psset]{optexp}[POE@]{frontlayer}[true]{}
\define@boolkey[psset]{optexp}[POE@]{optexpenv}[true]{}
\psset[optexp]{backlayer, frontlayer}%
%    \end{macrocode}
% Labels
%    \begin{macrocode}
\newcommand{\oelabel}[1]{#1}%
\define@key[psset]{optexp}{labelangle}{%
  \pst@checknum{#1}\POE@key@labelangle
}
\define@key[psset]{optexp}{labeloffset}{%
  \pst@checknum{#1}\POE@key@labeloffset
}
\define@key[psset]{optexp}{labelstyle}{%
  \def\POE@key@labelstyle{#1}%
}
\define@key[psset]{optexp}{labelalign}{%
  \def\POE@key@labelalign{#1}%
}
\define@choicekey+[psset]{optexp}{labelref}%
  [\val\nr]{absolute,relative,relgrav,global}%
  {%
    \ifcase\nr\relax
      \let\POE@key@labelref\POE@str@labelref@global
    \else
      \def\POE@key@labelref{#1}%
    \fi
  }{%
    \PackageError{pst-optexp}%
      {Unknown value '\val' for labelref}%
}%
\define@choicekey*+[psset]{optexp}{innerlabel}%
  [\val\nr]{true}[true]%
  {\ifcase\nr\relax
     \psset[optexp]{labeloffset=0, labelref=relative}%
   \fi}
  {\PackageError{pst-optexp}{Unknown value '\val' for innerlabel}}%
\define@key[psset]{optexp}{label}{%
  \pst@expandafter\POE@psset@@label{#1} {} {} {} {} {}\@nil
}%
\def\POE@psset@@label#1 #2 #3 #4 #5\@nil{%
  \edef\POE@temp{#4}%
  \ifx\POE@temp\@empty\else
    \expandafter\ifx\POE@temp.\else
      \psset[optexp]{labelref=#4}%
    \fi
  \fi
  \edef\POE@temp{#3}%
  \ifx\POE@temp\@empty\else
    \expandafter\ifx\POE@temp.\else
      \psset[optexp]{labelalign=#3}%
    \fi
  \fi
  \edef\POE@temp{#2}%
  \ifx\POE@temp\@empty\else
    \expandafter\ifx\POE@temp.\else
      \psset[optexp]{labelangle=#2}%
    \fi
  \fi
  \edef\POE@temp{#1}%
  \ifx\POE@temp\@empty\else
    \expandafter\ifx\POE@temp.\else
      \psset[optexp]{labeloffset=#1}%
    \fi
  \fi
}%
%    \end{macrocode}
% This is for internal use only, it sets the reference angle for the \opt{labelangle} parameter and can be different for some components.
%    \begin{macrocode}
\define@key[psset]{optexp}{ref@angle}{%
  \pst@checknum{#1}\POE@key@labelrefangle
}%
\psset[optexp]{%
  labeloffset=0.8,
  labelangle=0,
  labelstyle=,
  labelalign=c,
  labelref=relgrav,
  ref@angle=0
}%
%    \end{macrocode}
% External node
%    \begin{macrocode}
\define@choicekey+[psset]{optexp}{extnodealign}%
  [\val\nr]{rel,abs,relative,absolute}%
  {%
    \ifcase\nr\relax
      \let\POE@key@extnodealign\POE@str@relative
    \or
      \let\POE@key@extnodealign\POE@str@absolute
    \else
      \def\POE@key@extnodealign{#1}%
    \fi
  }%
  {\PackageError{pst-optexp}{Unknown value '\val' for extnodealign}}
%    \end{macrocode}
% This part was copied and adapted from \cs{psset@@ref} from pstricks.tex
%    \begin{macrocode}
\define@key[psset]{optexp}{extnode}{%
   \edef\POE@key@extnode{#1}%
   \ifx\@empty\POE@key@extnode\else
      \pst@expandafter\POE@psset@@extnode{#1}\@empty,,\@nil
   \fi
}%
\def\POE@key@extnode@xref{0}%
\def\POE@key@extnode@yref{0}%
\def\POE@psset@@extnode#1#2,#3,#4\@nil{%
  \def\POE@key@extnode@xref{0}%
  \def\POE@key@extnode@yref{0}%
  \ifx\@empty#3\@empty
    \@nameuse{POE@getref@#1}%
    \@nameuse{POE@getref@#2}%
  \else
    \pst@checknum{#1#2}\POE@key@extnode@xref%
    \pst@checknum{#3}\POE@key@extnode@yref%
  \fi
}%
\def\POE@getref@c{}%
\def\POE@getref@t{\def\POE@key@extnode@yref{1}}%
\def\POE@getref@b{\def\POE@key@extnode@yref{-1}}%
\def\POE@getref@l{\def\POE@key@extnode@xref{-1}}%
\def\POE@getref@r{\def\POE@key@extnode@xref{1}}%
\psset[optexp]{%
  extnode=\@empty, 
  extnodealign=abs
}%
%    \end{macrocode}
% Set the rotation reference point. For this to work properly, the components
% must define a proper \cs{component@ref} macro which sets the origin and
% sizes. See below for detailed information.
%    \begin{macrocode}
\define@key[psset]{optexp}{rotateref}{%
   \def\POE@temp{#1}%
   \ifx\@empty\POE@temp\else
      \pst@expandafter\POE@psset@@rotateref{#1}\@empty,,\@nil
   \fi
}%
\def\POE@key@rotate@xref{0}%
\def\POE@key@rotate@yref{0}%
\def\POE@psset@@rotateref#1#2,#3,#4\@nil{%
  \def\POE@key@rotate@xref{0}%
  \def\POE@key@rotate@yref{0}%
  \ifx\@empty#3\@empty
    \@nameuse{POE@getref@rotate@#1}%
    \@nameuse{POE@getref@rotate@#2}%
  \else
    \pst@checknum{#1#2}\POE@key@rotate@xref%
    \pst@checknum{#3}\POE@key@rotate@yref%
  \fi}%
\def\POE@getref@rotate@c{}%
\def\POE@getref@rotate@t{\def\POE@key@rotate@yref{1}}%
\def\POE@getref@rotate@b{\def\POE@key@rotate@yref{-1}}%
\def\POE@getref@rotate@l{\def\POE@key@rotate@xref{-1}}%
\def\POE@getref@rotate@r{\def\POE@key@rotate@xref{1}}%
\psset[optexp]{rotateref=c}%
%    \end{macrocode}
% Naming parameters.
%    \begin{macrocode}
\define@choicekey*[psset]{optexp}{namingscheme}%
  [\val\nr]{old,new}[new]{%
  \ifcase\nr\relax
%    \end{macrocode}
% Use the old naming scheme which was used in version 2.x.
%    \begin{macrocode}
    \edef\POE@str@basicname@default{tempNode}%
    \edef\POE@str@basicname@prefix{}%
    \gdef\POE@str@basicname@sep{Intern}%
    \edef\POE@str@extnode@postfix{ExtNode}%
  \or
    \edef\POE@str@basicname@default{@}%
    \edef\POE@str@basicname@prefix{OE@}%
    \gdef\POE@str@basicname@sep{}%
    \edef\POE@str@extnode@postfix{Ext}%
  \fi
}%
\psset[optexp]{namingscheme=new}%
\define@key[psset]{optexp}{b@sicname}{%
  \edef\POE@key@b@sicname{\POE@str@basicname@prefix#1}%
}%
\define@key[psset]{optexp}{compname}{%
  \ifPOE@insideobj\else
    \PackageError{pst-optexp}{compname allowed only inside an object}
  \fi
  \edef\POE@temp{#1}%
  \ifx\POE@temp\@empty
    \edef\POE@key@compname{\the\POE@cnt}%
  \else
    \edef\POE@key@compname{#1}%
  \fi
%    \end{macrocode}
% check if compname was already defined.
%    \begin{macrocode}
  \@expandtwoargs\in@{,\POE@key@compname,}{,\POE@complist,}%
  \ifin@
    \PackageWarning{pst-optexp}{%
      ^^Jcompname '\POE@key@compname' already used,\MessageBreak
      previous nodes will be overwritten!^^J
    }%
  \else
%    \end{macrocode}
%
% Use definition of \cs{XKV@addtolist@x} with an \cs{xdef} instead of \cs{edef} in order to keep the bookkeeping global.
%    \begin{macrocode}
    \xdef\POE@complist{%
      \POE@key@compname\ifx\POE@complist\@empty\else,\fi\POE@complist
    }%
  \fi
}%
\POE@insideobjtrue
\psset[optexp]{compname=\@empty}
\POE@insideobjfalse
%    \end{macrocode}
% Error handling.
%    \begin{macrocode}
\define@boolkey[psset]{optexp}[POE@]{pswarning}[true]{}
\psset[optexp]{pswarning=false}%
%    \end{macrocode}
%
% \subsection{Free-ray component parameters}
% Lens
%    \begin{macrocode}
\define@key[psset]{optexp}{lensheight}{%
  \pst@checknum{#1}\POE@key@lensheight
}
\define@key[psset]{optexp}{lenswidth}{%
  \pst@checknum{#1}\POE@key@lenswidth
  \ifdim\POE@key@lenswidth pt > 0pt
    \psset[optexp]{thicklens=true}
  \fi
}
\define@key[psset]{optexp}{lensradiusleft}{%
  \pst@checknum{#1}\POE@key@lensradiusleft
}
\define@key[psset]{optexp}{lensradiusright}{%
  \pst@checknum{#1}\POE@key@lensradiusright
}
\define@boolkey[psset]{optexp}[POE@]{thicklens}[true]{}
\define@key[psset]{optexp}{lensradius}{%
  \pst@expandafter\POE@psset@@lensradius{#1} {} {} {}\@nil
}%
\def\POE@psset@@lensradius#1 #2 #3\@nil{%
  \edef\POE@temp{#1}%
  \ifx\POE@temp\@empty\else
    \psset[optexp]{lensradiusleft=#1}%
  \fi
  \edef\POE@temp{#2}%
  \ifx\POE@temp\@empty
    \psset[optexp]{lensradiusright=#1}%
  \else
    \psset[optexp]{lensradiusright=#2}%
  \fi
}%
\define@key[psset]{optexp}{lens}{%
  \pst@expandafter\POE@psset@@lens{#1} {} {} {} {} {}\@nil
}%
\def\POE@psset@@lens#1 #2 #3 #4 #5\@nil{%
  \edef\POE@temp{#4}%
  \ifx\POE@temp\@empty\else
    \expandafter\ifx\POE@temp.\else
      \psset[optexp]{lenswidth=#4}%
    \fi
  \fi
  \edef\POE@temp{#3}%
  \ifx\POE@temp\@empty\else
    \expandafter\ifx\POE@temp.\else
      \psset[optexp]{lensheight=#3}
    \fi
  \fi
  \edef\POE@temp{#2}%
  \ifx\POE@temp\@empty
     \psset[optexp]{lensradiusright=#1}%
  \else
    \expandafter\ifx\POE@temp.\else
      \psset[optexp]{lensradiusright=#2}%
    \fi
  \fi
  \edef\POE@temp{#1}%
  \expandafter\ifx\POE@temp.\else
    \psset[optexp]{lensradiusleft=#1}%
  \fi
}%
\psset[optexp]{%
  lenswidth=0,
  lensheight=1,
  lensradiusleft=1,
  lensradiusright=1
}%
%    \end{macrocode}
% Pinhole
%    \begin{macrocode}
\define@key[psset]{optexp}{innerheight}{%
  \pst@checknum{#1}\POE@key@innerheight
}
\define@key[psset]{optexp}{outerheight}{%
  \pst@checknum{#1}\POE@key@outerheight
}
\define@key[psset]{optexp}{phlinewidth}{%
  \edef\POE@key@phlinewidth{#1}%
}
\define@key[psset]{optexp}{phwidth}{%
  \edef\POE@key@phwidth{#1}%
}
\psset[optexp]{%
  phlinewidth=2\pslinewidth,
  phwidth=0,
  outerheight=1,
  innerheight=0.1
}%
%    \end{macrocode}
% Crystal
%    \begin{macrocode}
\define@key[psset]{optexp}{crystalwidth}{%
  \pst@checknum{#1}\POE@key@crystalwidth
}
\define@key[psset]{optexp}{crystalheight}{%
  \pst@checknum{#1}\POE@key@crystalheight
}
\define@key[psset]{optexp}{crystalsize}{%
  \pst@expandafter\POE@psset@@crystalsize{#1} {} {} {}\@nil
}%
\def\POE@psset@@crystalsize#1 #2 #3\@nil{%
  \ifx\\#2\\%
    \PackageWarning{pst-optexp}{%
      Parameter 'crystalsize' requires two numbers.}%
  \fi
  \psset[optexp]{crystalwidth=#1}%
  \psset[optexp]{crystalheight=#2}%
}%
\define@key[psset]{optexp}{caxislength}{%
  \pst@checknum{#1}\POE@key@caxislength
}
\define@boolkey[psset]{optexp}[POE@]{voltage}[true]{}
\define@boolkey[psset]{optexp}[POE@]{caxisinv}[true]{}
\define@boolkey[psset]{optexp}[POE@]{lamp}[true]{}
\define@key[psset]{optexp}{lampscale}{%
  \pst@checknum{#1}\POE@key@lampscale
  \pst@divide{\POE@key@lampscale pt}{0.3pt}{\POE@key@lampscale}
  \addtopsstyle{CrystalLamp}{unit=\POE@key@lampscale}
  \PackageWarning{pst-optexp}{%
    Parameter 'lampscale' is deprecated, \MessageBreak
    use style 'CrystalLamp' instead.}%
}
\psset[optexp]{%
  crystalwidth=1.4,
  crystalheight=0.6,
  caxislength=0.3
}%
%    \end{macrocode}
% Box
%    \begin{macrocode}
\define@key[psset]{optexp}{optboxwidth}{%
  \pst@checknum{#1}\POE@key@optboxwidth
}
\define@key[psset]{optexp}{optboxheight}{%
  \pst@checknum{#1}\POE@key@optboxheight
}
\define@key[psset]{optexp}{optboxsize}{%
  \pst@expandafter\POE@psset@@optboxsize{#1} {} {} {}\@nil
}%
\def\POE@psset@@optboxsize#1 #2 #3\@nil{%
  \ifx\\#2\\%
    \PackageWarning{pst-optexp}{%
      Parameter 'optboxsize' requires two numbers.}%
  \fi
  \psset[optexp]{optboxwidth=#1, optboxheight=#2}%
}%
\psset[optexp]{%
  optboxwidth=1.4,
  optboxheight=0.8
}%
%    \end{macrocode}
% Plate
%    \begin{macrocode}
\define@key[psset]{optexp}{platelinewidth}{%
  \edef\POE@key@platelinewidth{#1}%
}
\define@key[psset]{optexp}{plateheight}{%
  \pst@checknum{#1}\POE@key@plateheight
}
\psset[optexp]{%
  plateheight=1,
  platelinewidth=2\pslinewidth
}%
%    \end{macrocode}
% Optical retardation plate, the height is the same as for \cs{optplate}.
%    \begin{macrocode}
\define@key[psset]{optexp}{platewidth}{%
  \pst@checknum{#1}\POE@key@platewidth
}
\define@key[psset]{optexp}{platesize}{%
  \pst@expandafter\POE@psset@@platesize{#1} {} {} {}\@nil
}%
\def\POE@psset@@platesize#1 #2 #3\@nil{%
  \ifx\\#2\\%
    \PackageWarning{pst-optexp}{%
      Parameter 'platesize' requires two numbers.}%
  \fi
  \psset[optexp]{platewidth=#1, plateheight=#2}%
}%
\psset[optexp]{platewidth=0.1}%
%    \end{macrocode}
% Detector
%    \begin{macrocode}
\define@key[psset]{optexp}{detsize}{%
  \pst@expandafter\POE@psset@@detsize{#1} {} {} {}\@nil
}%
\def\POE@psset@@detsize#1 #2 #3\@nil{%
  \ifx\\#2\\%
    \pst@checknum{#1}\POE@key@detsize
  \else
    \let\POE@key@detsize\@empty
    \pst@checknum{#1}\POE@key@detwidth
    \pst@checknum{#2}\POE@key@detheight
  \fi
}%
\define@choicekey*+[psset]{optexp}{dettype}[\val\nr]{round,diode}%
   {\edef\POE@key@dettype{\val}}
   {\PackageError{pst-optexp}{Unknown value '\val' for dettype}}
\newpsstyle{DetectorStyle}{}
\psset[optexp]{%
  detsize=0.8,
  dettype=round
}%
%    \end{macrocode}
% Polarization
%    \begin{macrocode}
\define@key[psset]{optexp}{polsize}{%
  \pst@checknum{#1}\POE@key@polsize
}
\define@key[psset]{optexp}{pollinewidth}{%
  \edef\POE@key@pollinewidth{#1}%
  \PackageWarning{pst-optexp}{%
    Parameter 'pollinewidth' is deprecated, \MessageBreak
    use style 'Polarization'.}%
}%
%    \end{macrocode}
% This is defined manually, to avoid printing the warning inside the key definition above.
%    \begin{macrocode}
\def\POE@key@pollinewidth{0.7\pslinewidth}%
\newpsstyle{Polarization}{%
  linewidth=\POE@key@pollinewidth, 
  arrowscale=0.8, dotsize=3\pslinewidth}
\define@choicekey+[psset]{optexp}{poltype}%
  [\val\nr]{parallel,misc,perp,rcirc,lcirc}%
  {\edef\POE@key@poltype{#1}}
  {\PackageError{pst-optexp}{Unknown value '\val' for poltype}%
}
\psset[optexp]{%
  poltype=parallel,
  polsize=0.6
}%
%    \end{macrocode}
% Optical diode
%    \begin{macrocode}
\define@key[psset]{optexp}{optdiodesize}{%
  \pst@checknum{#1}\POE@key@optdiodesize
}
\psset[optexp]{optdiodesize=0.8}%
%    \end{macrocode}
% Dove prism
%    \begin{macrocode}
\define@key[psset]{optexp}{doveprismsize}{%
  \pst@expandafter\POE@psset@@doveprismsize{#1} {} {} {}\@nil
}%
\def\POE@psset@@doveprismsize#1 #2 #3\@nil{%
  \ifx\\#2\\%
    \pst@checknum{#1}\POE@key@doveprismheight
    \pstFPmul\POE@key@doveprismwidth{3}{#1}
  \else
    \pst@checknum{#1}\POE@key@doveprismwidth
    \pst@checknum{#2}\POE@key@doveprismheight
  \fi
}%
\psset[optexp]{doveprismsize=0.6}%
%    \end{macrocode}
% Glan-Thompson prism
%    \begin{macrocode}
\define@key[psset]{optexp}{glanthompsongap}{%
  \pst@checknum{#1}\POE@key@glanthompsongap
}%
\define@key[psset]{optexp}{glanthompsonwidth}{%
  \pst@checknum{#1}\POE@key@glanthompsonwidth
}%
\define@key[psset]{optexp}{glanthompsonheight}{%
  \pst@checknum{#1}\POE@key@glanthompsonheight
}%
\define@key[psset]{optexp}{glanthompsonsize}{%
  \pst@expandafter\POE@psset@@glanthompsonsize{#1} {} {} {}\@nil
}%
\def\POE@psset@@glanthompsonsize#1 #2 #3\@nil{%
  \ifx\\#2\\%
    \PackageWarning{pst-optexp}{%
      Parameter 'glanthompsonsize' requires two numbers.}%
  \fi
  \psset[optexp]{glanthompsonwidth=#1, glanthompsonheight=#2}%
}%
\psset[optexp]{%
  glanthompsongap=0,
  glanthompsonsize=1 0.5
}%
%    \end{macrocode}
% Beamsplitter
%    \begin{macrocode}
\define@key[psset]{optexp}{bssize}{%
  \pst@checknum{#1}\POE@key@bssize
}
\define@key[psset]{optexp}{bsstyle}{%
  \edef\POE@key@bsstyle{#1}%
}
\psset[optexp]{%
  bssize=0.8,
  bsstyle=cube
}%
%    \end{macrocode}
% Mirror
%    \begin{macrocode}
\define@key[psset]{optexp}{mirrorwidth}{%
  \pst@checknum{#1}\POE@key@mirrorwidth
}
\define@key[psset]{optexp}{mirrorlinewidth}{%
  \edef\POE@key@mirrorlinewidth{#1}%
}
\define@choicekey*[psset]{optexp}{mirrortype}%
  [\val\nr]{piezo,extended,plain,semitrans}{%
  \edef\POE@key@mirrortype{#1}%
}
\define@key[psset]{optexp}{mirrordepth}{%
  \pst@checknum{#1}\POE@key@mirrordepth
}
\define@key[psset]{optexp}{mirrorradius}{%
  \pst@expandafter\POE@psset@@mirrorradius{#1} {} {} {}\@nil
}%
\def\POE@psset@@mirrorradius#1 #2 #3\@nil{%
  \pst@checknum{#1}\POE@key@mirrorradius
  \ifx\\#2\\%
    \def\POE@key@mirrorradiusB{}%
  \else
    \pst@checknum{#2}\POE@key@mirrorradiusB
    \ifdim\POE@key@mirrorradiusB pt=0pt\else
      \PackageWarning{optexp}{%
        The second value for option 'mirrorradius' must be 0.}%
    \fi
  \fi
}%
\define@boolkey[psset]{optexp}[POE@]{variable}[true]{}
\psset[optexp]{%
  mirrorwidth=1,
  mirrordepth=0.15,
  mirrorradius=0,
  mirrortype=plain,
  mirrorlinewidth=2\pslinewidth
}%
%    \end{macrocode}
% Grating
%
% These are the old \opt{optgrid*} parameters, which have been deprecated.
%    \begin{macrocode}
\define@key[psset]{optexp}{optgridcount}{%
  \pst@checknum{#1}\POE@key@gratingcount
  \PackageWarning{pst-optexp}{%
    Parameter 'optgridcount' is deprecated,\MessageBreak
    use 'gratingcount' instead.}%
}%
\define@key[psset]{optexp}{optgridwidth}{%
  \pst@checknum{#1}\POE@key@gratingwidth
  \PackageWarning{pst-optexp}{%
    Parameter 'optgridwidth' is deprecated,\MessageBreak
    use 'gratingwidth' instead.}%
}%
\define@key[psset]{optexp}{optgridheight}{%
  \pst@checknum{#1}\POE@key@gratingheight
  \PackageWarning{pst-optexp}{%
    Parameter 'optgridheight' is deprecated,\MessageBreak
    use 'gratingheight' instead.}%
}%
\define@choicekey*[psset]{optexp}{optgridtype}%
  [\val\nr]{binary,blazed}{%
  \edef\POE@key@gratingtype{#1}%
  \PackageWarning{pst-optexp}{%
    Parameter 'optgridtype' is deprecated,\MessageBreak
    use 'gratingtype' instead.}%
}%
\define@key[psset]{optexp}{optgriddepth}{%
  \pst@checknum{#1}\POE@key@gratingdepth
  \PackageWarning{pst-optexp}{%
    Parameter 'optgriddepth' is deprecated,\MessageBreak
    use 'gratingdepth' instead.}%
}%
\define@key[psset]{optexp}{optgridlinewidth}{%
  \edef\POE@key@gratinglinewidth{#1}%
  \PackageWarning{pst-optexp}{%
    Parameter 'optgridlinewidth' is deprecated,\MessageBreak
    use 'gratinglinewidth' instead.}%
}%
%    \end{macrocode}
% These are the new grating parameters.
%    \begin{macrocode}
\define@key[psset]{optexp}{gratingcount}{%
  \pst@checknum{#1}\POE@key@gratingcount
}
\define@key[psset]{optexp}{gratingwidth}{%
  \pst@checknum{#1}\POE@key@gratingwidth
}
\define@key[psset]{optexp}{gratingheight}{%
  \pst@checknum{#1}\POE@key@gratingheight
}
\define@choicekey*[psset]{optexp}{gratingtype}%
  [\val\nr]{binary,blazed}{%
  \edef\POE@key@gratingtype{#1}%
}
\define@key[psset]{optexp}{gratingdepth}{%
  \pst@checknum{#1}\POE@key@gratingdepth
}
\define@key[psset]{optexp}{gratinglinewidth}{%
  \edef\POE@key@gratinglinewidth{#1}%
}
\define@choicekey+[psset]{optexp}{gratingalign}%
  [\val\nr]{t,c,top,center}%
  {%
    \ifcase\nr\relax
      \let\POE@key@gratingalign\POE@str@top
    \or
      \let\POE@key@gratingalign\POE@str@center
    \else
      \def\POE@key@gratingalign{#1}%
    \fi}%
  {\PackageError{pst-optexp}{Unknown value '\val' for gratingalign}}
\define@boolkey[psset]{optexp}[POE@]{reverse}[true]{}
\psset[optexp]{%
  gratingcount=10,
  gratingwidth=1,
  gratingheight=0.15,
  gratingdepth=0.075,
  gratingtype=blazed,
  gratinglinewidth=0.7\pslinewidth,
  gratingalign=t
}%
%    \end{macrocode}
% Penta prism
%    \begin{macrocode}
\define@key[psset]{optexp}{pentaprismsize}{%
  \pst@checknum{#1}\POE@key@pentaprismsize
}
\psset[optexp]{pentaprismsize=0.7}
%    \end{macrocode}
% Right-angle prism
%    \begin{macrocode}
\define@key[psset]{optexp}{raprismsize}{%
  \pst@checknum{#1}\POE@key@raprismsize
}
\psset[optexp]{raprismsize=1.5}
%    \end{macrocode}
% Prism
%    \begin{macrocode}
\define@key[psset]{optexp}{prismsize}{%
  \pst@checknum{#1}\POE@key@prismsize
}
\define@key[psset]{optexp}{prismangle}{%
  \pst@checknum{#1}\POE@key@prismangle
}
\define@choicekey+[psset]{optexp}{prismalign}[\val\nr]%
  {auto,center}%
  {\def\POE@key@prismalign{#1}}%
  {\PackageError{pst-optexp}{Unknown value '\val' for prismalign}}%
\psset[optexp]{%
  prismsize=1,
  prismangle=60,
  prismalign=auto
}%
%    \end{macrocode}
%
% Optdipole and Opttripole
%    \begin{macrocode}
\define@key[psset]{optexp}{optdipolesize}{%
  \pst@expandafter\POE@psset@@optdipolesize{#1} {} {} {}\@nil
}%
\def\POE@psset@@optdipolesize#1 #2 #3\@nil{%
  \ifx\\#2\\%
    \def\POE@key@optdipoleheight{0}%
  \else
    \pst@checknum{#2}\POE@key@optdipoleheight
  \fi
  \pst@checknum{#1}\POE@key@optdipolewidth
}%
\psset[optexp]{optdipolesize=0 0}%
% \subsection{Parameters of fiber-optical components}
% \subsubsection{fiber}
%    \begin{macrocode}
\define@key[psset]{optexp}{fiberloops}{%
  \pst@checknum{#1}\POE@key@fiberloops
}
\define@key[psset]{optexp}{fiberloopradius}{%
  \pst@checknum{#1}\POE@key@fiberloopradius
}
\define@key[psset]{optexp}{fiberloopsep}{%
  \pst@checknum{#1}\POE@key@fiberloopsep
}
\psset[optexp]{%
  fiberloops=3,
  fiberloopradius=0.4,
  fiberloopsep=0.3
}%
%    \end{macrocode}
% \subsubsection{optfilter}
%    \begin{macrocode}
\define@key[psset]{optexp}{filtersize}{%
  \pst@checknum{#1}\POE@key@filtersize
}
\define@choicekey+[psset]{optexp}{filtertype}[\val\nr]%
   {bandstop,bandpass,lowpass,highpass}%
   {\def\POE@key@filtertype{#1}}%
   {\PackageError{pst-optexp}{Unknown value '\val' for filtertype}}
\define@key[psset]{optexp}{filterangle}{%
  \pst@checknum{#1}\POE@key@filterangle
}
\newpsstyle{FilterStyle}{}
\psset[optexp]{%
  filterangle=0,
  filtersize=0.8,
  filtertype=bandpass
}%
%    \end{macrocode}
% Polarization controller
%    \begin{macrocode}
\define@key[psset]{optexp}{polcontrolsize}{%
  \pst@checknum{#1}\POE@key@polcontrolsize
}
\define@choicekey+[psset]{optexp}{polcontroltype}[\val\nr]%
   {linear,triangle}%
   {\def\POE@key@polcontroltype{#1}}%
   {\PackageError{pst-optexp}{Unknown value '\val' for polcontroltype}}
\psset[optexp]{%
  polcontrolsize=0.15,
  polcontroltype=linear
}%
%    \end{macrocode}
%
% \subsubsection{optamp}
%    \begin{macrocode}
\define@key[psset]{optexp}{optampsize}{%
  \pst@expandafter\POE@psset@@optampsize{#1} {} {} {}\@nil
}%
\def\POE@psset@@optampsize#1 #2 #3\@nil{%
  \ifx\\#2\\%
    \pst@checknum{#1}\POE@key@optampheight
    \pstFPmul\POE@key@optampwidth{0.866}{#1}
  \else
    \pst@checknum{#1}\POE@key@optampwidth
    \pst@checknum{#2}\POE@key@optampheight
  \fi
}%
\psset[optexp]{optampsize=0.8}
%    \end{macrocode}
% Mach-Zehnder modulator
%    \begin{macrocode}
\define@key[psset]{optexp}{optmzmsize}{%
  \pst@expandafter\POE@psset@@optmzmsize{#1} {} {} {}\@nil
}%
\def\POE@psset@@optmzmsize#1 #2 #3\@nil{%
  \ifx\\#2\\%
    \pst@checknum{#1}\POE@key@optmzmheight
    \pstFPmul\POE@key@optmzmwidth{1.6}{#1}
  \else
    \pst@checknum{#1}\POE@key@optmzmwidth
    \pst@checknum{#2}\POE@key@optmzmheight
  \fi
}%
\psset[optexp]{optmzmsize=0.8}
%    \end{macrocode}
% \subsubsection{Isolator}
%    \begin{macrocode}
\define@key[psset]{optexp}{isolatorsize}{%
  \pst@expandafter\POE@psset@@isolatorsize{#1} {} {} {}\@nil
}%
\def\POE@psset@@isolatorsize#1 #2 #3\@nil{%
  \ifx\\#2\\%
    \pst@checknum{#1}\POE@key@isolatorheight
    \pstFPmul\POE@key@isolatorwidth{1.6}{#1}
  \else
    \pst@checknum{#1}\POE@key@isolatorwidth
    \pst@checknum{#2}\POE@key@isolatorheight
  \fi
}%
\psset[optexp]{isolatorsize=0.6}%
%    \end{macrocode}
% Fiber polarizer
%    \begin{macrocode}
\define@key[psset]{optexp}{fiberpolsize}{%
  \pst@expandafter\POE@psset@@fiberpolsize{#1} {} {} {}\@nil
}%
\def\POE@psset@@fiberpolsize#1 #2 #3\@nil{%
  \ifx\\#2\\%
    \pst@checknum{#1}\POE@key@fiberpolheight
    \pstFPmul\POE@key@fiberpolwidth{1.6}{#1}
  \else
    \pst@checknum{#1}\POE@key@fiberpolwidth
    \pst@checknum{#2}\POE@key@fiberpolheight
  \fi
}%
\psset[optexp]{fiberpolsize=0.6}%
%    \end{macrocode}
% Optical switch
%    \begin{macrocode}
\define@key[psset]{optexp}{switchsize}{%
  \pst@expandafter\POE@psset@@switchsize{#1} {} {} {}\@nil
}%
\def\POE@psset@@switchsize#1 #2 #3\@nil{%
  \pst@checknum{#1}\POE@key@switchwidth
  \ifx\\#2\\%
    \pst@checknum{#1}\POE@key@switchheight
  \else
    \pst@checknum{#2}\POE@key@switchheight
  \fi
}%
\define@choicekey+[psset]{optexp}{switchstyle}%
  [\val\nr]{opened,closed}%
  {\edef\POE@key@switchstyle{#1}}%
  {\PackageError{pst-optexp}{Unknown value '\val' for switchstyle}}
\psset[optexp]{%
  switchsize=0.8,
  switchstyle=opened
}%
%    \end{macrocode}
% \subsubsection{Fiber delay line}
%    \begin{macrocode}
\define@key[psset]{optexp}{fdlsize}{%
  \pst@expandafter\POE@psset@@fdlsize{#1} {} {} {}\@nil
}%
\def\POE@psset@@fdlsize#1 #2 #3\@nil{%
  \ifx\\#2\\%
    \pst@checknum{#1}\POE@key@fdlheight
    \pstFPmul\POE@key@fdlwidth{1.6}{#1}
  \else
    \pst@checknum{#1}\POE@key@fdlwidth
    \pst@checknum{#2}\POE@key@fdlheight
  \fi
}%
\psset[optexp]{fdlsize=0.6}%
%    \end{macrocode}
% Fiber collimator 
%    \begin{macrocode}
\define@key[psset]{optexp}{fibercolsize}{%
  \pst@expandafter\POE@psset@@fibercolsize{#1} {} {} {}\@nil
}%
\def\POE@psset@@fibercolsize#1 #2 #3\@nil{%
  \ifx\\#2\\%
    \pst@checknum{#1}\POE@key@fibercolheight
    \pstFPmul\POE@key@fibercolwidth{0.866}{#1}
  \else
    \pst@checknum{#1}\POE@key@fibercolwidth
    \pst@checknum{#2}\POE@key@fibercolheight
  \fi
}%
\psset[optexp]{fibercolsize=0.3}%
%    \end{macrocode}
% Optical Circulator
%    \begin{macrocode}
\define@key[psset]{optexp}{optcircsize}{%
  \pst@checknum{#1}\POE@key@optcircsize
}%
\define@key[psset]{optexp}{optcircangleA}{%
  \pst@checknum{#1}\POE@key@optcircangleA
}%
\define@key[psset]{optexp}{optcircangleB}{%
  \pst@checknum{#1}\POE@key@optcircangleB
}%
\define@key[psset]{optexp}{optcircangle}{%
  \pst@expandafter\POE@psset@@optcircangle{#1} {} {} {}\@nil
}%
\def\POE@psset@@optcircangle#1 #2 #3\@nil{%
  \ifx\\#2\\%
    \PackageError{pst-optexp}{optcircangle requires two numbers}%
  \else\ifx\\#1\\%
    \PackageError{pst-optexp}{optcircangle requires two numbers}%
  \else
    \psset[optexp]{optcircangleA=#1, optcircangleB=#2}%
  \fi\fi
}%
\psset[optexp]{%
  optcircsize=0.8, 
  optcircangle=-160 -20
}%
\newpsstyle{OptCircArrow}{unit=0.7, arrows=->, arrowinset=0}
%    \end{macrocode}
%
% \subsubsection{Coupler}
%    \begin{macrocode}
\define@key[psset]{optexp}{couplersize}{%
  \pst@expandafter\POE@psset@@couplersize{#1} {} {} {}\@nil
}%
\def\POE@psset@@couplersize#1 #2 #3\@nil{%
  \ifx\\#2\\%
    \pstFPmul\POE@key@couplerheight{0.8}{#1}
    \pstFPmul\POE@key@couplerwidth{2}{#1}
  \else
    \pst@checknum{#1}\POE@key@couplerwidth
    \pst@checknum{#2}\POE@key@couplerheight
  \fi
}%
\define@key[psset]{optexp}{couplersep}{%
  \pst@checknum{#1}\POE@key@couplersep
}
\define@choicekey+[psset]{optexp}{couplertype}%
  [\val\nr]{none,elliptic,ellipse,cross,rectangle}%
  {%
    \edef\POE@key@couplertype{#1}
    \ifx\POE@key@couplertype\POE@str@couplertype@elliptic
      \let\POE@key@couplertype\POE@str@couplertype@ellipse
    \fi
  }%
  {\PackageError{pst-optexp}{Unknown value '\val' for couplertype}}
\define@key[psset]{optexp}{align}{%
  \psset[optexp]{coupleralign=#1}%
  \PackageWarning{pst-optexp}{%
    Parameter 'align' is deprecated,\MessageBreak
    use 'coupleralign' instead.}%
}
\define@choicekey+[psset]{optexp}{coupleralign}%
  [\val\nr]{t,b,c,top,bottom,center}%
  {%
    \ifcase\nr\relax
      \let\POE@key@coupleralign\POE@str@top
    \or
      \let\POE@key@coupleralign\POE@str@bottom
    \or
      \let\POE@key@coupleralign\POE@str@center
    \else
      \def\POE@key@coupleralign{#1}%
    \fi}%
  {\PackageError{pst-optexp}{Unknown value '\val' for coupleralign}}
\psset[optexp]{%
  couplersize=0.2,
  couplersep=0.05,
  coupleralign=center,
  couplertype=elliptic
}%
%    \end{macrocode}
%
% \subsection{Fiber box}
%
%    \begin{macrocode}
\define@key[psset]{optexp}{fiberboxheight}{%
  \pst@checknum{#1}\POE@key@fiberboxheight
}%
\define@key[psset]{optexp}{fiberboxwidth}{%
  \pst@checknum{#1}\POE@key@fiberboxwidth
}%
\define@key[psset]{optexp}{fiberboxsize}{%
  \pst@expandafter\POE@psset@@fiberboxsize{#1} {} {} {}\@nil
}%
\def\POE@psset@@fiberboxsize#1 #2 #3\@nil{%
  \psset[optexp]{fiberboxwidth=#1}
  \ifx\\#2\\%
    \psset[optexp]{fiberboxheight=0}%
  \else
    \psset[optexp]{fiberboxheight=#2}%
  \fi
}%
\define@key[psset]{optexp}{fiberboxsepin}{%
  \def\POE@key@fiberboxsepin{#1}
}%
\define@key[psset]{optexp}{fiberboxsepout}{%
  \def\POE@key@fiberboxsepout{#1}%
}%
\define@key[psset]{optexp}{fiberboxcount}{%
  \pst@expandafter\POE@psset@@fiberboxcount#1\@nil
}%
\def\POE@psset@@fiberboxcount#1x#2\@nil{%
  \ifx\\#1\\%
    \def\POE@key@fiberboxcountin{1}%
  \else
    \def\POE@key@fiberboxcountin{#1}%
  \fi
  \ifx\\#2\\%
    \def\POE@key@fiberboxcountout{1}%
  \else
    \def\POE@key@fiberboxcountout{#2}
  \fi
}%
\psset[optexp]{%
  fiberboxsize=1,
  fiberboxsepin=0.2,
  fiberboxsepout=0.2,
  fiberboxcount=2x2}
%    \end{macrocode}
% \subsection{Beam-connection parameters}
% The keys related to the \cs{draw*} macros.
%
% Connect a component directly with its reference nodes using \cs{drawbeam}.
%    \begin{macrocode}
\define@boolkey[psset]{optexp}[POE@]{beam}[true]{}
%    \end{macrocode}
%    \begin{macrocode}
\define@key[psset]{optexp}{refractiveindex}{%
  \psset[optexp]{n=#1}%
  \PackageWarning{pst-optexp}{%
    Option 'refractiveindex' is deprecated,\MessageBreak
    use 'n' instead.}%
}%
\define@key[psset]{optexp}{n}{%
  \POE@parsealg{n}#1\@nil
}
\def\POE@parsealg#1#2#3\@nil{%
  \ifx#2*\relax
    \POE@@parsealg#3\@nil
    \expandafter\let\csname POE@key@#1\endcsname\POE@tempA
  \else
    \@namedef{POE@key@#1}{[#2#3] }%
  \fi
}
\def\POE@@parsealg#1#2\@nil{%
  \edef\POE@tempA{tx@Dict begin (#1#2) AlgParser end }%
}
\define@key[psset]{optexp}{beamangle}{%
  \edef\POE@key@beamangle{#1}%
}%
\define@key[psset]{optexp}{beampos}{%
  \edef\POE@key@beampos{#1}%
}%
\define@key[psset]{optexp}{beamdiv}{%
  \edef\POE@key@beamdiv{#1}%
}%
\define@key[psset]{optexp}{beamwidth}{%
  \edef\POE@key@beamwidth{#1}%
}%
\define@boolkey[psset]{optexp}[POE@]{startinside}[true]{}%
\define@boolkey[psset]{optexp}[POE@]{stopinside}[true]{}%
\define@boolkey[psset]{optexp}[POE@]{beaminsidefirst}[true]{}%
\define@boolkey[psset]{optexp}[POE@]{beaminsidelast}[true]{}%
\define@choicekey+[psset]{optexp}{savebeampoints}%
  [\val\nr]{true,false}[true]{%
    \ifcase\nr\relax
      \def\POE@key@savebeampoints{1}
    \or
      \def\POE@key@savebeampoints{0}
    \fi
  }{%
    \ifnum9<1#1
      \def\POE@key@savebeampoints{#1}
    \else
      \PackageError{pst-optexp}%
        {savebeampoints must be a positive integer or 0}%
    \fi
    \@expandtwoargs\in@{,\POE@key@savebeampoints,}{,\POE@beamlist,}%
    \ifin@\else
      \xdef\POE@beamlist{%
        \POE@key@savebeampoints
        \ifx\POE@beamlist\@empty\else,\fi\POE@beamlist
      }%
    \fi
}%
\define@choicekey+[psset]{optexp}{loadbeampoints}%
  [\val\nr]{true,false}[true]{%
    \ifcase\nr\relax
      \def\POE@key@loadbeampoints{1}%
    \or
      \def\POE@key@loadbeampoints{0}%
    \fi
  }{%
    \ifnum9<1#1
      \def\POE@key@loadbeampoints{#1}%
    \else
      \PackageError{pst-optexp}%
        {loadbeampoints must be a positive integer or 0}%
    \fi
    \@expandtwoargs\in@{,\POE@key@loadbeampoints,}{,\POE@beamlist,}%
    \ifin@\else
      \xdef\POE@beamlist{%
        \POE@key@loadbeampoints
        \ifx\POE@beamlist\@empty\else,\fi\POE@beamlist
      }%
    \fi
}%
\define@key[psset]{optexp}{loadbeam}[true]{%
  \setkeys+[psset]{optexp}{loadbeampoints=#1}%
  \ifdim\POE@key@loadbeampoints pt>0pt
    \POE@loadbeamtrue
  \else
    \POE@loadbeamfalse
  \fi
}%
\define@key[psset]{optexp}{savebeam}[true]{%
  \setkeys+[psset]{optexp}{savebeampoints=#1}%
  \ifdim\POE@key@savebeampoints pt>0pt
    \POE@savebeamtrue
  \else
    \POE@savebeamfalse
  \fi
}%
\define@boolkey[psset]{optexp}[POE@]{beaminside}[true]{}%
\define@boolkey[psset]{optexp}[POE@]{allowbeaminside}[true]{}%
\define@boolkey[psset]{optexp}[POE@]{forcebeaminside}[true]{}%
\define@boolkey[psset]{optexp}[POE@]{raytrace}[true]{}%
\define@boolkey[psset]{optexp}[POE@]{useNA}[true]{}%
\define@key[psset]{optexp}{beampathskip}{%
  \pst@checknum{#1}\POE@key@beampathskip
}%
\define@choicekey+[psset]{optexp}{beamalign}%
  [\val\nr]{rel,abs,relative,absolute}%
  {%
    \ifcase\nr\relax
      \let\POE@key@beamalign\POE@str@relative
    \or
      \let\POE@key@beamalign\POE@str@absolute
    \else
      \def\POE@key@beamalign{#1}%
    \fi
  }%
  {\PackageError{pst-optexp}{Unknown value '\val' for beamalign}}
\define@key[psset]{optexp}{ArrowInsideMinLength}{%
  \def\POE@key@ArrowInsideMinLength{#1}%
}%
\define@key[psset]{optexp}{ArrowInsideMaxLength}{%
  \def\POE@key@ArrowInsideMaxLength{#1}%
}%
\psset[optexp]{%
  raytrace=true
  ,useNA=true
  ,startinside=false
  ,stopinside=false
  ,allowbeaminside=true
  ,forcebeaminside=false
  ,beaminside=true
  ,beaminsidefirst=false
  ,beaminsidelast=false
  ,loadbeam=false
  ,savebeam=true
  ,loadbeampoints=false
  ,savebeampoints=true
  ,beamangle=0
  ,beampos=\@empty
  ,beamalign=relative
  ,beamwidth=0
  ,beamdiv=0
  ,n=1.5
  ,beampathskip=0
  ,ArrowInsideMinLength=0.2
  ,ArrowInsideMaxLength=-1
}%
%    \end{macrocode}
%
% \subsection{Fiber-connection parameters}
% Select which fibers are drawn automatically. The parameters \opt{fiber},
% \opt{fiberin} and \opt{fiberout} do not only select which fibers are drawn,
% but do also enable fiber connecting for the free-ray components. So you should
% use these switches only locally, or they must be followed by a
% \opt{fiber@=false}. (Need to rethink this part\ldots).
%    \begin{macrocode}
\define@key[psset]{optexp}{fiber}[all]{%
  \POE@psset@fibercheck#1\@nil
}
\def\POE@psset@fibercheck#1#2\@nil{%
  \ifx#1*\relax
    \ifx\\#2\\%
      \psset[optexp]{fiber@preset=all}%
    \else
      \psset[optexp]{fiber@preset=#2}%
    \fi
  \else\ifx#1+\relax
    \ifx\\#2\\%
      \psset[optexp]{fiber@all=all}%
    \else
      \psset[optexp]{fiber@all=#2}%
    \fi
  \else
    \psset[optexp]{fiber@all=#1#2}%
    \psset[optexp]{fiber@preset=#1#2}%
  \fi\fi
}%
\define@choicekey*+[psset]{optexp}{fiber@preset}%
  [\val\nr]{false,none,true,all}[all]{%
  \ifcase\nr\relax
    \POE@getfiberpreset@none
  \or
    \POE@getfiberpreset@none
  \or
    \POE@getfiberpreset@all
  \or
    \POE@getfiberpreset@all
  \fi
}{%
  \ifx\@empty\val
    \POE@getfiberpreset@none
  \else
    \pst@expandafter\POE@psset@@fiberpreset{#1}\@empty,,\@nil
  \fi
}%
\def\POE@psset@@fiberpreset#1#2,#3,#4\@nil{%
  \POE@getfiberpreset@all
  \ifx\\#3\\%
    \@nameuse{POE@getfiberpreset@#1}%
    \@nameuse{POE@getfiberpreset@#2}%
  \fi
}%
\def\POE@getfiberpreset@none{%
  \psset[optexp]{fiberpreset@=false}%
}%
\def\POE@getfiberpreset@all{%
  \psset[optexp]{%
    fiberpreset@, fiberpresetin@, fiberpresetout@,
    fiberpresetin@top, fiberpresetin@bottom, 
    fiberpresetout@top, fiberpresetout@bottom}%
}%
\def\POE@getfiberpreset@t{%
  \psset[optexp]{fiberpresetin@bottom=false, fiberpresetout@bottom=false}}%
\def\POE@getfiberpreset@b{%
  \psset[optexp]{fiberpresetin@top=false, fiberpresetout@top=false}}%
\def\POE@getfiberpreset@l{\psset[optexp]{fiberpresetout@=false}}%
\def\POE@getfiberpreset@r{\psset[optexp]{fiberpresetin@=false}}%
\let\POE@getfiberpreset@i\POE@getfiberpreset@l
\let\POE@getfiberpreset@o\POE@getfiberpreset@r
%    \end{macrocode}
%
% This code is for all components, fiber-optical and free-ray.
%    \begin{macrocode}
\define@choicekey*+[psset]{optexp}{fiber@all}%
  [\val\nr]{false,none,true,all}[all]{%
  \ifcase\nr\relax
    \POE@getfiber@none
  \or
    \POE@getfiber@none
  \or
    \POE@getfiber@all
  \or
    \POE@getfiber@all
  \fi
}{%
  \ifx\@empty\val
    \POE@getfiber@none
  \else
    \pst@expandafter\POE@psset@@fiber{#1}\@empty,,\@nil
  \fi
}%
\def\POE@psset@@fiber#1#2,#3,#4\@nil{%
  \POE@getfiber@all
  \ifx\@empty#3\@empty
    \@nameuse{POE@getfiber@#1}%
    \@nameuse{POE@getfiber@#2}%
  \fi
}%
\def\POE@getfiber@none{%
  \psset[optexp]{fiber@=false}%
}%
\def\POE@getfiber@all{%
  \psset[optexp]{%
    fiber@, fiberin@, fiberout@,
    fiberin@top, fiberin@bottom, 
    fiberout@top, fiberout@bottom}%
}%
\def\POE@getfiber@t{%
  \psset[optexp]{fiberin@bottom=false, fiberout@bottom=false}}%
\def\POE@getfiber@b{%
  \psset[optexp]{fiberin@top=false, fiberout@top=false}}%
\def\POE@getfiber@l{\psset[optexp]{fiberout@=false}}%
\def\POE@getfiber@r{\psset[optexp]{fiberin@=false}}%
\let\POE@getfiber@i\POE@getfiber@l
\let\POE@getfiber@o\POE@getfiber@r
%    \end{macrocode}
% These are the internal boolkeys for the fiber choices done with \opt{fiberin},
% \opt{fiberout} and \opt{fiber}. Do not use them directly.
%    \begin{macrocode}
\define@boolkey[psset]{optexp}[POE@]{fiber@}[true]{}
\define@boolkey[psset]{optexp}[POE@]{nofiber@}[true]{}
\define@boolkey[psset]{optexp}[POE@]{fiberin@}[true]{}
\define@boolkey[psset]{optexp}[POE@]{fiberin@top}[true]{}
\define@boolkey[psset]{optexp}[POE@]{fiberin@bottom}[true]{}
\define@boolkey[psset]{optexp}[POE@]{fiberout@}[true]{}
\define@boolkey[psset]{optexp}[POE@]{fiberout@top}[true]{}
\define@boolkey[psset]{optexp}[POE@]{fiberout@bottom}[true]{}
\define@boolkey[psset]{optexp}[POE@]{fiberpreset@}[true]{}
\define@boolkey[psset]{optexp}[POE@]{nofiberpreset@}[true]{}
\define@boolkey[psset]{optexp}[POE@]{fiberpresetin@}[true]{}
\define@boolkey[psset]{optexp}[POE@]{fiberpresetin@top}[true]{}
\define@boolkey[psset]{optexp}[POE@]{fiberpresetin@bottom}[true]{}
\define@boolkey[psset]{optexp}[POE@]{fiberpresetout@}[true]{}
\define@boolkey[psset]{optexp}[POE@]{fiberpresetout@top}[true]{}
\define@boolkey[psset]{optexp}[POE@]{fiberpresetout@bottom}[true]{}
\psset[optexp]{fiber=*all}%
\define@key[psset]{optexp}{fiberangleA}{%
  \pst@checknum{#1}\POE@key@fiberangleA
}%
\define@key[psset]{optexp}{fiberangleB}{%
  \pst@checknum{#1}\POE@key@fiberangleB
}%
\define@choicekey+[psset]{optexp}{fiberalign}%
  [\val\nr]{rel,abs,relative,center,absolute}%
  {%
    \ifcase\nr\relax
      \let\POE@key@fiberalign\POE@str@relative
    \or
      \let\POE@key@fiberalign\POE@str@absolute
    \else
      \def\POE@key@fiberalign{#1}%
    \fi
  }%
  {\PackageError{pst-optexp}{Unknown value '\val' for fiberalign}}%
\define@key[psset]{optexp}{fiberstyle}{%
  \@ifundefined{nc#1}%
    {\PackageError{pst-optexp}{Unknown value '#1' for fiberstyle}}%
    {\def\POE@key@fiberstyle{#1}}}
\psset[optexp]{%
  fiberangleA=0,
  fiberangleB=0,
  fiberalign=relative,
  fiberstyle=curve
}%
%    \end{macrocode}
% Which nodes to take for the automatic fiber connections.
%    \begin{macrocode}
\define@choicekey+[psset]{optexp}{startnode}%
  [\val\nr]{auto,1,2,3,4,N}%
  {\edef\POE@key@startnode{\val}}
  {\PackageError{pst-optexp}{Unknown startnode number '\val'}}
\define@choicekey+[psset]{optexp}{stopnode}[\val\nr]{auto,1,2,3,4,N}%
   {\edef\POE@key@stopnode{\val}}
   {\PackageError{pst-optexp}{Unknown stopnode number '\val'}}
\psset[optexp]{%
  startnode=auto,
  stopnode=auto
}%
%    \end{macrocode}
%
% \section{Layering}
%    \begin{macrocode}
\newenvironment{optexp}{\Collect@Body\POE@collect}{}
\long\def\POE@collect#1{%
  \psset[optexp]{optexpenv}
  \global\POE@oldcnt=\POE@cnt
  \bgroup
    \psset[optexp]{backlayer=true, frontlayer=false}#1%
  \egroup
  \gdef\POE@complist{}\global\POE@cnt=\POE@oldcnt\relax
  \psset[optexp]{backlayer=false, frontlayer=true}%
  #1\ignorespaces}%
%    \end{macrocode}
% \begin{macro}{\backlayer}
%    \begin{macrocode}
\def\backlayer#1{\ifPOE@backlayer #1\fi\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\frontlayer}
%    \begin{macrocode}
\def\frontlayer#1{\ifPOE@frontlayer #1\fi\ignorespaces}%
%    \end{macrocode}
% \end{macro}
%
% \section{Connection code}
% \subsection{drawfiber}
% \begin{macro}{\POE@getnode}
%    \begin{macrocode}
\def\POE@getnode#1#2\@nil{%
  \ifx(#1\relax%)
    \POE@getcoor#1#2
    \edef\POE@temp{{\pst@coor}}%
  \else
    \POE@checkcompname{#1#2}%
    \edef\POE@temp{/\oenode{}{#1#2}\space}%
  \fi%
}%
%    \end{macrocode}
% \begin{macro}{\POE@getcoor}
%    \begin{macrocode}
\def\POE@getcoor(#1){\pst@@getcoor{#1}}%
%    \end{macrocode}
% \end{macro}
% \end{macro}
% 
% \begin{macro}{\drawfiber}
%    \begin{macrocode}
\def\drawfiber{\drawfiber@{Fiber}}%
\def\drawfiber@#1{%
  \ifPst@custom\else
    \def\pst@par{style=#1}%
  \fi
  \@ifnextchar[%]
    {\drawfiber@i}{\drawfiber@i[]}%
}%
\def\drawfiber@i[#1]{%
  \addafter@par{#1}%
  \drawfiber@ii}

\def\drawfiber@ii{%
  \@ifnextchar(%)
    {\drawfiber@iii}%
    {\@ifnextchar\bgroup{\drawfiber@iv}{}}%
}%
\def\drawfiber@iii(#1){\drawfiber@iv{(#1)}}%
\def\drawfiber@iv#1{%
  \def\POE@tempe{#1}\drawfiber@ii@
}%
\def\drawfiber@ii@{%
  \@ifnextchar(%)
    {\drawfiber@iii@}%
    {\@ifnextchar\bgroup{\drawfiber@iv@}{}}%
}%
\def\drawfiber@iii@(#1){\drawfiber@iv@{(#1)}}%
\def\drawfiber@iv@#1{%
  \expandafter\drawfiber@v\expandafter{\POE@tempe}{#1}%
  \def\POE@tempe{#1}\drawfiber@ii@}%
\def\drawfiber@v#1#2{%
  \begingroup
    \let\psk@angleA\relax
    \let\psk@angleB\relax
    \use@par
    \let\POE@angleA\psk@angleA
    \let\POE@angleB\psk@angleB
    \ifx\psk@angleA\relax
      \def\psk@angleA{0 }%3
    \fi
    \ifx\psk@angleB\relax
      \def\psk@angleB{0 }%
    \fi
    \def\POE@tempa{#1}
    \ifx\POE@tempa\@empty
      \edef\POE@comps{/\oenode{}{}\space}
    \else
      \expandafter\POE@getnode#1\@nil
      \edef\POE@comps{\POE@temp}
    \fi
    \def\POE@tempb{#2}
    \ifx\POE@tempb\@empty
      \edef\POE@comps{/\oenode{}{}\space \POE@comps}
    \else
      \expandafter\POE@getnode#2\@nil
      \edef\POE@comps{\POE@temp\space \POE@comps}
    \fi
    \ifPOE@backlayer
      \ifx\POE@key@startnode\POE@str@auto\else
        \POE@pnode{/\POE@key@startnode\space \POE@comps exch pop 
          \POE@dict{GetIfcOrNodeCoord} \tx@UserCoor}{@@A}
      \fi
      \ifx\POE@key@stopnode\POE@str@auto\else
        \POE@pnode{/\POE@key@stopnode\space \POE@comps pop 
                 \POE@dict{GetIfcOrNodeCoord} \tx@UserCoor}{@@B}
      \fi
      \ifx\POE@key@startnode\POE@str@auto
        \ifx\POE@key@stopnode\POE@str@auto
          \POE@pnode{\POE@comps exch \POE@dict{NearestNode} 
                   \tx@UserCoor}{@@A}
          \POE@pnode{\POE@comps pop
                     \POE@dict{/N@@@A @GetCenter ToVec NearestNode} 
                     \tx@UserCoor}{@@B}
        \else
          \POE@pnode{\POE@comps exch pop /N@@@B 
                   \POE@dict{@GetCenter ToVec NearestNode} 
                   \tx@UserCoor}{@@A}
        \fi
      \else\ifx\POE@key@stopnode\POE@str@auto
        \POE@pnode{\POE@comps pop /N@@@A
                 \POE@dict{@GetCenter ToVec NearestNode} 
                 \tx@UserCoor}{@@B}
      \fi\fi
      \pst@getcoor{@@A}\POE@tempa
      \pst@getcoor{@@B}\POE@tempb
      \ifx\POE@angleA\relax
        \ifx\POE@key@fiberalign\POE@str@absolute
          \psset{angleA=\POE@key@fiberangleA}%
        \else
          \psset{angleA=! \POE@dict{%
            \POE@tempb \POE@tempa \POE@comps exch 
            \POE@key@fiberalign\space RelFiberAngle
            \POE@key@fiberangleA\space add }
          }%
        \fi
      \fi
      \ifx\POE@angleB\relax
        \ifx\POE@key@fiberalign\POE@str@absolute
          \psset{angleB=\POE@key@fiberangleB}%
        \else
          \psset{angleB=! \POE@dict{%
            \POE@tempa \POE@tempb \POE@comps 
            \POE@key@fiberalign\space RelFiberAngle
            \POE@key@fiberangleB\space add}
          }%
        \fi
      \fi
      \@nameuse{nc\POE@key@fiberstyle}{@@A}{@@B}
    \fi
  \endgroup
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{POE@pnode}
%   Do some trickery to define \cs{pnode} inside \cs{pscustom}, which is
%   required if one wants to use \cs{drawfiber} inside \cs{pscustom}.
%    \begin{macrocode}
\def\POE@pnode#1#2{%
  \ifPst@custom
    \code{%
      gsave 
        /currentpoint load stopped { 0 0 moveto } if 
        1 8.3021995 div dup neg scale 
        tx@NodeDict begin 
          {#1 \tx@ScreenCoor } false /N@#2 10 {InitPnode} 
          /NodeScale {} def NewNode 
        end 
      grestore 
    }%
  \else
    \pnode(!#1){#2}
  \fi
}%
%    \end{macrocode}
% \end{macro}
% 
% \subsection{drawbeam}
%
% \begin{macro}{\begin@BeamObj}
%    \begin{macrocode}
\def\begin@BeamObj{%
  \addbefore@par{n=n}%
  \begin@SpecialObj%
  \addto@pscode{%
     \pst@optexpdict
     /loadbeampoints \POE@key@loadbeampoints\space def 
     /loadbeam \ifPOE@loadbeam true \else false \fi def
     /beamangle \POE@key@beamangle\space def
     /beamdiv \POE@key@beamdiv\space def
     /savebeampoints \POE@key@savebeampoints\space def
     /savebeam \ifPOE@savebeam true \else false \fi def
     /beaminsidefirst \ifPOE@beaminsidefirst true \else false \fi def
     /beaminsidelast \ifPOE@beaminsidelast true \else false \fi def
     /beaminside \ifPOE@beaminside true \else false \fi def
     /startinside \ifPOE@startinside true \else false \fi def
     /stopinside \ifPOE@stopinside true \else false \fi def
     /connectifc \ifPOE@raytrace false \else true \fi def
     /beamalign 
       \ifx\POE@key@beamalign\POE@str@absolute\space 
         absolute
       \else 
         relative
       \fi def
     /beampathskip \POE@key@beampathskip\space def
     /useNA \ifPOE@useNA true \else false \fi def
  }%
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\begin@WideBeamObj}
%    \begin{macrocode}
\def\begin@WideBeamObj{%
  \addbefore@par{style=Beam}%
  \begin@BeamObj
  \let\pst@linetype\pst@arrowtype
  \pst@addarrowdef%
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\begin@SingleBeamObj}
%    \begin{macrocode}
\let\begin@SingleBeamObj\begin@WideBeamObj
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\drawbeam}
%    \begin{macrocode}
\def\drawbeam{\pst@object{drawbeam}}%
\def\drawbeam@i{%
  \def\POE@conntable{,a-a,b-b,A-A,B-B}%
  \begin@SingleBeamObj
  \POE@getcomps[\drawbeam@ii%
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\drawwidebeam}
%    \begin{macrocode}
\def\drawwidebeam{\pst@object{drawwidebeam}}%
\def\drawwidebeam@i{%
  \begin@WideBeamObj
  \POE@getcomps[\drawwidebeam@ii%
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\POE@beam@use@pscode}
%
%   This is a hack which allows us to leave the names and coordinates of the
%   beam end points on the stack after the \opt{@endspecial} call. This replaces
%   \nxLcs{use@pscode} in \nxLcs{end@BeamObj}. These values on the stack must be
%   consumed directly after closing the beam object.
%    \begin{macrocode}
\def\POE@beam@use@pscode{%
  \pstverb{%
    \pst@dict
    \tx@STP
    \pst@newpath
    \psk@origin
    \psk@swapaxes
    \pst@code
    end
    count /ocount exch def
  }%
  \gdef\pst@code{}%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\end@BeamObj}
%    \begin{macrocode}
\def\end@BeamObj{%
  \addto@pscode{ end }%
  \let\psk@fillstyle\relax
  \ifPOE@optexpenv
    \ifPOE@frontlayer
%    \end{macrocode}
% Erase all beam-drawing code and leave only \opt{false} on the stack to 
% indicate that no beampoints should be stored.
%    \begin{macrocode}
      \def\pst@code{ false false }%
    \fi
  \fi
  \let\use@pscode\POE@beam@use@pscode
  \end@SpecialObj%
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\drawbeam@ii}
%    \begin{macrocode}
\def\drawbeam@ii{%
  \ifx\POE@key@conn\@empty
    \drawbeam@iii
  \else
    \drawbeam@compat
  \fi
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\drawbeam@iii}
%    \begin{macrocode}
\def\drawbeam@iii{%
  \ifodd
%    \end{macrocode}
% Do not draw anything only if both linestyle and ArrowInside are not set.
%    \begin{macrocode}
    \ifx\pslinestyle\@none\ifx\psk@ArrowInside\@empty 1\else 0\fi\else 0\fi
    \addto@pscode{ cleartomark false false }%
  \else
    \addto@pscode{%
%    \end{macrocode}
% I need to pack it this way in order to avoid replacing the \opt{n} inside the
% code here. This must be done later, when it refers to the correct refractive
% indices.
%    \begin{macrocode}
      {/nbeam {\POE@key@n cvx exec} bind def
       \ifPOE@pswarning
         /Warning /PrintWarning load def
       \else
         /Warning /pop load def
       \fi}%
      [ \POE@key@beampos\space counttomark dup 
      0 eq { 
        pop 0 0 
      } {
        1 eq {
          0 exch
        } if
      } ifelse \tx@ScreenCoor] cvx
      \POE@key@beamangle\space
      currentdict /lastBeamPointTmp undef
      currentdict /lastVecTmp undef
      loadbeampoints 1 ge 
      tx@NodeDict /N@\oenodeBeam{\POE@key@loadbeampoints} known and {
        /N@\oenodeBeam{\POE@key@loadbeampoints} @GetCenter ToVec 
        /lastBeamPointTmp ED
      } if
      currentdict /lastVec\POE@key@loadbeampoints\space known 
      loadbeam and {
        /lastVecTmp /lastVec\POE@key@loadbeampoints\space load def
      } if
      TraceBeam 
      \POE@strokesinglebeam
      savebeampoints 1 ge
      currentdict /lastBeamPointTmp known and dup { 
        lastBeamPointTmp 
        /N@\oenodeBeam{\POE@key@savebeampoints}\space 4 -1 roll
      } if 
      savebeam currentdict /lastVecTmp known and dup {
        /prevVec\POE@key@savebeampoints\space
        currentdict /prevVecTmp known { prevVecTmp }{ 0 0 } ifelse
        /lastVec\POE@key@savebeampoints\space lastVecTmp 7 -1 roll
      } if
    }%
  \fi
  \end@BeamObj
  \POE@Verb{%
    { tx@OptexpDict begin ToVec def ToVec def end } if
    { \tx@NodeScale @NewNode } if
  }%
}%
%    \end{macrocode}
% \end{macro}
% This fix is necessary for pst-node since version 1.21.
%    \begin{macrocode}
\def\tx@NodeScale{%
  \pst@nodedict 
    /NodeScale {\ifx\pstnodescale\@undefined\else\pstnodescale\fi} def 
  end }
%    \end{macrocode}
% 
% \begin{macro}{\POE@strokesinglebeam}
%    \begin{macrocode}
\def\POE@strokesinglebeam{%
  gsave 
    /Lineto /lineto load def
    \tx@Drawbeam 
    \tx@setlinejoin
    \pst@number\pslinewidth SLW
    \pst@usecolor\pslinecolor
    \tx@setStrokeTransparency
    \@nameuse{psls@\pslinestyle}
  grestore
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\drawwidebeam@ii}
%    \begin{macrocode}
\def\drawwidebeam@ii{%
  \def\pst@fill##1{ gsave ##1 grestore }%
  \addto@pscode{%
    {/nbeam {\POE@key@n cvx exec} bind def
      \ifPOE@pswarning
        /Warning /PrintWarning load def
      \else
        /Warning /pop load def
      \fi}%
  }%
%    \end{macrocode}
% arrange and create the input vectors
%    \begin{macrocode}
  \addto@pscode{%
    \POE@key@beamangle\space dup
    \POE@key@beamdiv\space 0.5 mul dup 4 -1 roll add 3 1 roll sub
  }%
%    \end{macrocode}
% the start positions
%    \begin{macrocode}
  \addto@pscode{%
    [ \POE@key@beampos\space counttomark dup
      0 eq {
        pop 0 0 
      } {
        1 eq {
          0 exch 
        } if
      } ifelse
      mark \POE@key@beamwidth\space counttomark 0 eq {
        0 
      } {
        0.5 mul
      } ifelse
      exch pop
      3 copy add \tx@ScreenCoor\space ToVec 
      5 1 roll sub \tx@ScreenCoor
    ] cvx
  }%
%    \end{macrocode}
% rearrange options
%    \begin{macrocode}
  \addto@pscode{ exch 4 -1 roll 4 2 roll exch }% 
%    \end{macrocode}
% stroke and/or fill
%    \begin{macrocode}
  \addto@pscode{%
    counttomark mark exch 2 add 1 roll
    gsave
      \ifx\psk@fillstyle\relax
        currentdict /fillBeam undef
      \else
        /fillBeam {\psk@fillstyle} def
      \fi
      /strokeBeam 
        \ifx\pslinestyle\@none false \else true \fi 
        \ifx\psk@ArrowInside\@empty false \else true \fi or def
      [/lastBeamPointTmpLow /lastBeamPointTmpUp
      /lastVecTmpLow /lastVecTmpUp]
      {currentdict exch undef} forall
      tx@NodeDict /N@\oenodeBeamLow{\POE@key@loadbeampoints} known
      tx@NodeDict /N@\oenodeBeamUp{\POE@key@loadbeampoints} known
      loadbeampoints 1 ge and and {
        /N@\oenodeBeamLow{\POE@key@loadbeampoints} @GetCenter ToVec 
        /lastBeamPointTmpLow ED
        /N@\oenodeBeamUp{\POE@key@loadbeampoints} @GetCenter ToVec 
        /lastBeamPointTmpUp ED
      } if
      loadbeam 
      currentdict /lastVecLow\POE@key@loadbeampoints\space known and 
      currentdict /lastVecUp\POE@key@loadbeampoints\space known and {
        /lastVecTmpLow /lastVecLow\POE@key@loadbeampoints\space load def
        /lastVecTmpUp /lastVecUp\POE@key@loadbeampoints\space load def
      } if
      TraceAndFillWideBeam
    grestore pop % pop off the mark
%    \end{macrocode}
% Rearrange the points so that we can use two Drawbeam calls.
% 
%    \begin{macrocode}
    counttomark 0 gt strokeBeam and {
      counttomark dup /cnta ED /cntb ED
      cnta 6 idiv {
        cnta 3 roll /cnta cnta 3 sub def
        /cntb cntb 3 sub def
        cntb 3 roll /cntb cntb 3 sub def
      } repeat
      counttomark 2 idiv 1 add mark exch 1 roll
      \POE@strokesinglebeam
      \POE@strokesinglebeam
    } {
      pop % pop off the mark
    } ifelse
    currentdict /fillBeam known strokeBeam or
    savebeampoints 1 ge and
    currentdict /lastBeamPointTmpLow known and
    currentdict /lastBeamPointTmpUp known and dup {
      lastBeamPointTmpLow /N@\oenodeBeamLow{\POE@key@savebeampoints}
      lastBeamPointTmpUp /N@\oenodeBeamUp{\POE@key@savebeampoints}
      7 -1 roll
    } if
    currentdict /fillBeam known strokeBeam or 
    savebeam and
    currentdict /lastVecTmpLow known and
    currentdict /lastVecTmpUp known and dup {
      /prevVecLow\POE@key@savebeampoints\space /prevVecUp\POE@key@savebeampoints\space
      currentdict /prevVecLow known currentdict /prevVecUp known and {
        prevVecLow 3 -1 roll prevVecUp
      } { 
        0 0 3 -1 roll 0 0
      } ifelse
      /lastVecLow\POE@key@savebeampoints\space lastVecTmpLow
      /lastVecUp\POE@key@savebeampoints\space lastVecTmpUp
      13 -1 roll
    } if
  }%
  \end@BeamObj
  \POE@Verb{%
    { tx@OptexpDict begin 4 { ToVec def } repeat end } if
    { \tx@NodeScale @NewNode @NewNode } if 
  }%
}%
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
\pst@def{Drawbeam}<
%    \end{macrocode}
% Remove trailing empty line parts.
%    \begin{macrocode}
    { counttomark 6 le {
        exit
      } if
      3 index not {
        pop pop pop 
      }{ 
        exit
      } ifelse
    } loop
%    \end{macrocode}
% Remove heading empty line parts. Note, that the first point must not have
% 'draw = true', because it is the starting point which we have to move to.
%    \begin{macrocode}
    { counttomark 3 le {
        exit
      } if
      counttomark 3 sub index not {
        counttomark -3 roll pop pop pop
      }{
        exit
      } ifelse
    } loop
%    \end{macrocode}
%    \begin{macrocode}
  counttomark 3 le {
%    \end{macrocode}
% first ray misses the next interface or is even parallel to the input interface.
%    \begin{macrocode}
    cleartomark
  }{
%    \end{macrocode}
% This is the /Line definition from \opt{pstricks-add}, adapted to the beam path
% structure which includes the boolean values to indicate if a line is drawn, or
% if we use moveto. There was no way to patch the original definition to account
% for the moveto parts and avoid duplicating the code.
%    \begin{macrocode}
  counttomark 3 div cvi /N ED
  (\psk@ArrowInside) length 0 gt { 
    \ifx\psk@arrowA\arrowType@H   % do we have a Hook arrow at the beginning?
      \pst@number\pshooklength  % yes 
    \else
      \psk@arrowsize\space CLW mul add dup \psk@arrowlength\space mul exch \psk@arrowinset mul neg add  
    \fi
    /arrowlength exch def 
    6 copy pop				% copy all four values for the arrow line
    /y1 ED /x1 ED pop /y2 ED /x2 ED 	% save them
    /Alpha y2 y1 sub x2 x1 sub Atan def % the gradient of the line
    pop 3 -1 roll 5 1 roll 
    ArrowA 
    x1 Alpha cos arrowlength mul add	% dx add
    y1 Alpha sin arrowlength mul add	% dy add, to get the current point at the end of the arrow tip
    5 -1 roll 3 1 roll true
    /N N 1 sub def
    N {
      6 copy pop 
      /y1 ED /x1 ED pop /y2 ED /x2 ED /draw ED
%    \end{macrocode}
% Check for line segment length and draw the arrow only, if the segment is long
% enough. This is in first place to avoid drawing an inside arrow for the
% pinhole which has three interfaces instead of one so that it can be used as
% real spatial filter.
%    \begin{macrocode}
      x1 y1 x2 y2 @ABDist dup
      \POE@key@ArrowInsideMinLength\space\pst@number\psunit mul ge 
      exch \POE@key@ArrowInsideMaxLength\space\pst@number\psunit mul dup 0 lt 
        3 1 roll le or and {
        x1 y1
        \psk@ArrowInsidePos\space 1 gt {
          /Alpha y2 y1 sub x2 x1 sub Atan def
          /ArrowPos \psk@ArrowInsideOffset\space def
          /dArrowPos \psk@ArrowInsidePos\space abs def
          \psk@ArrowInsideNo\space cvi {
            /ArrowPos ArrowPos dArrowPos add def
            x1 Alpha cos ArrowPos mul add
            y1 Alpha sin ArrowPos mul add
            6 index { ArrowInside } if
            pop pop
          } repeat
        }{
          /ArrowPos \psk@ArrowInsideOffset\space def
          /dArrowPos \psk@ArrowInsideNo 1 gt {%
            1.0 \psk@ArrowInsideNo 1.0 add div
          }{\psk@ArrowInsidePos } ifelse def
            \psk@ArrowInsideNo\space cvi {
              /ArrowPos ArrowPos dArrowPos add def
              x2 x1 sub ArrowPos mul x1 add
              y2 y1 sub ArrowPos mul y1 add
              6 index { ArrowInside } if
              pop pop
            } repeat
        } ifelse
        pop pop
      } if
      draw {Lineto}{moveto} ifelse
    } repeat
  }{
    pop 5 copy 3 -1 roll pop 
    ArrowA pop pop pop pop
    counttomark 3 idiv -1 2 {
      pop {
        lineto
      }{
        moveto
      } ifelse
    } for
  } ifelse
  {CP 4 2 roll ArrowB lineto pop pop } {moveto} ifelse
%    \end{macrocode}
% remove the mark
%    \begin{macrocode}
  pop
  } ifelse
>
%    \end{macrocode}
% 
%    \begin{macrocode}
\def\POE@getcomprange#1-#2\@nil{%
  \ifx\\#2\\%
    \ifx\\#1\\%
%    \end{macrocode}
% empty option, use the current component ID
%    \begin{macrocode}
      \edef\POE@firstcomp{\the\POE@cnt}%
      \edef\POE@lastcomp{\the\POE@cnt}%
    \else
%    \end{macrocode}
% A single number was given
%    \begin{macrocode}
      \edef\POE@firstcomp{#1}%
      \edef\POE@lastcomp{#1}%
%    \end{macrocode}
% Check if the number is valid, otherwise quit with an error.
%    \begin{macrocode}
      \ifodd
        \ifnum 0<\POE@firstcomp\ifnum\POE@lastcomp>\the\POE@cnt \@ne\else\z@\fi\else\@ne\fi
        \PackageError{pst-optexp}%
          {Component ID \POE@firstcomp\space is not valid, 
           \ifnum\the\POE@cnt=0 no components have been defined\else
           valid range is from 1 to \the\POE@cnt\fi}
      \fi
    \fi
  \else
    \ifx\\#1\\%
      \edef\POE@firstcomp{1}%
    \else
      \edef\POE@firstcomp{#1}%
    \fi
    \POE@getlastcomp#2%
    \ifnum\POE@firstcomp>\the\POE@cnt
      \ifnum\POE@lastcomp>\the\POE@cnt\relax
        \PackageError{pst-optexp}%
          {All components \POE@firstcomp-\POE@lastcomp\space out of range}%
      \fi
    \fi
    \ifnum\POE@firstcomp<1
      \PackageWarning{pst-optexp}%
        {Component ID \POE@firstcomp\space is not valid, setting to 1.}%
      \def\POE@firstcomp{1}%
    \else\ifnum\POE@firstcomp>\the\POE@cnt
      \PackageWarning{pst-optexp}%
        {Component ID \POE@firstcomp\space is not valid, setting to \MessageBreak
         the last defined value (\the\POE@cnt).}%
      \edef\POE@firstcomp{\the\POE@cnt}%
    \fi\fi
    \ifnum\POE@lastcomp>\the\POE@cnt
      \PackageWarning{pst-optexp}%
        {Component ID \POE@lastcomp\space is not valid, setting to \MessageBreak
         the last defined value (\the\POE@cnt).}%
      \edef\POE@lastcomp{\the\POE@cnt}%
    \else\ifnum\POE@lastcomp<1
      \PackageWarning{pst-optexp}%
        {Component ID \POE@lastcomp\space is not valid, setting to 1.}%
      \def\POE@lastcomp{1}%
    \fi\fi
  \fi
}%
\def\POE@getlastcomp#1-{%
  \ifx\@empty#1\relax
    \ifnum\POE@firstcomp>\the\POE@cnt\relax
      \PackageError{pst-optexp}{All components \POE@firstcomp- out of range.}%
    \fi
    \edef\POE@lastcomp{\the\POE@cnt}%
  \else
    \edef\POE@lastcomp{#1}%
  \fi
}%
%    \end{macrocode}
%
% \begin{macro}{\POE@getcomps}
%    \begin{macrocode}
\def\POE@getcomps#1#2{%
  \ifx\POE@key@conn\@empty
    \def\POE@aftercomps{\addto@pscode{#1 \POE@comps }#2}%
  \else
    \def\POE@aftercomps{#2}%
  \fi
  \def\POE@comps{}%
  \POE@getcomps@i%
}%
\def\POE@getcomps@i{%
  \@ifnextchar(%)
    {\POE@getplanenode@i}%
    {\POE@getcomps@ii}
}%
\def\POE@getcomps@ii{%
  \@ifnextchar\bgroup{\POE@getcomps@iii}{\POE@aftercomps}%
}%
\def\POE@getcomps@iii#1{%
  \def\POE@temp{#1\@empty}%
  \expandafter\POE@getcomps@iv\POE@temp\@nil
}%
\def\POE@getcomps@iv#1#2\@nil{%
  \edef\POE@temp{#1}%
  \ifx\POE@temp\@empty
    \POE@getcomp{(\oenode{}{})}%
  \else\ifx(#1\relax%)
    \POE@getplanenode#1#2%
  \else\ifnum9<1#1\relax
    \POE@getcomprange#1#2-\@nil
    \POE@getcomp{%
      (\POE@str@basicname@prefix\POE@str@basicname@default)
      \POE@firstcomp\space\POE@lastcomp\space GetCompRange %
    }%
  \else\ifx-#1\relax
    \POE@getcomprange#1#2-\@nil
    \POE@getcomp{%
      (\POE@str@basicname@prefix\POE@str@basicname@default) 
      \POE@firstcomp\space\POE@lastcomp\space GetCompRange %
    }%
  \else
    \POE@checkcompname{#1#2}%
    \POE@getcomp{(\oenode{}{#1#2})}%
  \fi\fi\fi\fi%
  \POE@getcomps@i%
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\POE@getplanenode}
%    \begin{macrocode}
\def\POE@getplanenode(#1){%
  \pst@@getcoor{#1}%
  \ifx\POE@key@conn\@empty
    \advance\POE@nodecnt by 1
    \POE@getcomp{%
      {\pst@coor} {0 1} 
      (\POE@str@basicname@default N@\the\POE@nodecnt) 
      {\tx@UserCoor} NewTempNodeComp 
      (\POE@str@basicname@default N@\the\POE@nodecnt)
    }%
  \else
    \POE@getcomp{{\pst@coor} }%
  \fi
}%
\def\POE@getplanenode@i(#1){\POE@getplanenode(#1)\POE@getcomps@i}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\POE@getcomp}
%    \begin{macrocode}
\def\POE@getcomp#1{%
  \ifx\POE@comps\@empty
    \edef\POE@tempc{#1}%
  \else
    \edef\POE@tempd{#1}%
  \fi
  \edef\POE@comps{#1 \POE@comps}%
}%
%    \end{macrocode}
% \end{macro}
% 
% \subsection{Automatic connections}
%
% \begin{macro}{\POE@drawInternalConnections}
%    \begin{macrocode}
\def\POE@drawInternalConnections{%
  \ifx\POE@key@conn\@empty
    \POE@drawInternalConnectionsNew
  \else
    \POE@drawInternalConnectionsOld
  \fi
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\POE@drawPresetFibers}
%    \begin{macrocode}
\def\POE@drawPresetFibers{%
  \ifPOE@endbox
    \ifPOE@fiberpresetin@
      \drawfiber@{FiberIn}{(\oenodeRefA{})}{}
    \fi
  \else\ifPOE@startbox
    \ifPOE@fiberpresetout@
      \drawfiber@{FiberOut}{}{(\oenodeRefB{})}
    \fi
  \else
    \ifPOE@fiberpresetin@
      \drawfiber@{FiberIn}{(\oenodeRefA{})}{}
    \fi
    \ifPOE@fiberpresetout@
      \drawfiber@{FiberOut}{}{(\oenodeRefB{})}
    \fi
  \fi\fi
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\POE@drawInternalConnectionsNew}
%    \begin{macrocode}
\def\POE@drawInternalConnectionsNew{%
  \ifPOE@beam
    \ifPOE@endbox
      \drawbeam[raytrace=false]{(\oenodeRefA{})}{}
    \else\ifPOE@startbox
      \drawbeam[raytrace=false]{}{(\oenodeRefB{})}
    \else
      \drawbeam[raytrace=false]{(\oenodeRefA{})}{}{(\oenodeRefB{})}
    \fi\fi
  \else\ifPOE@fiber@
%    \end{macrocode}
% This is equivalent to the code in \cs{POE@drawPresetFibers}.
%    \begin{macrocode}
    \ifPOE@endbox
      \ifPOE@fiberin@
        \drawfiber@{FiberIn}{(\oenodeRefA{})}{}
      \fi
    \else\ifPOE@startbox
      \ifPOE@fiberout@
        \drawfiber@{FiberOut}{}{(\oenodeRefB{})}
      \fi
    \else
      \ifPOE@fiberin@
        \drawfiber@{FiberIn}{(\oenodeRefA{})}{}
      \fi
      \ifPOE@fiberout@
        \drawfiber@{FiberOut}{}{(\oenodeRefB{})}
      \fi
    \fi\fi
  \fi\fi
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\POE@drawInternalConnectionsOld}
%    \begin{macrocode}
\def\POE@drawInternalConnectionsOld{%
  \ifPOE@endbox
    \@nameuse{\POE@connIn}
  \else
    \ifPOE@fiber@
      \ifPOE@fiberin@
        \@nameuse{\POE@connIn}
      \fi
      \ifPOE@fiberout@
        \@nameuse{\POE@connOut}
      \fi
    \else
      \ifPOE@connjoin
        \def\POE@tempa{POE@conn@in@i}%
        \ifx\POE@tempa\POE@connIn
          \def\POE@tempb{POE@conn@out@o}
          \ifx\POE@tempb\POE@connOut
            \pscustom[style=Beam, linejoin=\POE@key@connjoin]{%
              \@nameuse{\POE@connIn}\@nameuse{\POE@connOut}}%
          \else\ifx\@empty\POE@connOut
            \pscustom[style=Beam, linejoin=\POE@key@connjoin]{%
              \@nameuse{\POE@connIn}\@nameuse{\POE@connOut}}%
          \else
            \@nameuse{\POE@connIn}\@nameuse{\POE@connOut}%
          \fi\fi
        \else
          \def\POE@tempa{POE@conn@in@o}%
          \ifx\POE@tempa\POE@connIn
            \def\POE@tempb{POE@conn@out@o}
            \ifx\POE@tempb\POE@connOut
              \@nameuse{\POE@connIn}\@nameuse{\POE@connOut}%
            \else\ifx\@empty\POE@connOut
              \pscustom[style=Beam, linejoin=\POE@key@connjoin]{%
                \@nameuse{\POE@connIn}\@nameuse{\POE@connOut}}%
            \else
              \pscustom[style=Beam, linejoin=\POE@key@connjoin]{%
                \@nameuse{\POE@connIn}\@nameuse{\POE@connOut}}%
            \fi\fi
          \else
            \@nameuse{\POE@connIn}\@nameuse{\POE@connOut}%
          \fi
        \fi
      \else
        \@nameuse{\POE@connIn}\@nameuse{\POE@connOut}%
      \fi
    \fi
  \fi
}%
%    \end{macrocode}
% \end{macro}
%
% \subsection{Old connection code}
%
% The old connection code for backward compatibility to version 2.x. As this is
% obsolete and was broken by design, there is no need to comment on this.
%    \begin{macrocode}
\def\optexp@nodeA{\oenodeIn{}}%
\def\optexp@nodeB{\oenodeOut{}}%
\define@key[psset]{optexp}{connjoin}{%
 \edef\POE@temp{#1}%
 \ifnum\POE@temp<0
   \POE@connjoinfalse
 \else\ifnum\POE@temp>2
   \POE@connjoinfalse
 \else
   \POE@connjointrue
   \edef\POE@key@connjoin{\POE@temp}
 \fi\fi
}%
\def\POE@key@conn{}%
\define@key[psset]{optexp}{conn}{%
  \edef\POE@key@conn{#1}%
  \expandafter\POE@psset@@conn\POE@key@conn\@empty-\@empty\@nil
  \if@pst\else
    \PackageError{pst-optexp}{Bad connection specification: #1}%
  \fi
}%
\def\POE@psset@@conn#1-#2\@empty#3\@nil{%
  \@psttrue
  \def\POE@next##1,#1-##2,##3\@nil{\def\POE@temp{##2}}%
  \expandafter\POE@next\POE@conntable,#1-#1,\@nil
  \@ifundefined{POE@conn@in@\POE@temp}%
    {\@pstfalse\def\POE@connIn{}}%
    {\edef\POE@connIn{POE@conn@in@\POE@temp}}%
  \@ifundefined{POE@conn@out@#2}%
    {\@pstfalse\def\POE@connOut{}}%
    {\def\POE@connOut{POE@conn@out@#2}}%
}%
\def\POE@connIn{}%
\def\POE@connOut{}%
\def\POE@conntable{,o-o,i-i,f-f}%
\def\POE@conn@out@{\ifPOE@insideobj\else\POE@conn@out@a\fi}%
\def\POE@conn@in@{\ifPOE@insideobj\else\POE@conn@in@a\fi}%
\def\POE@conn@in@o{%
  \psline[style=Beam](\oenodeRefA{})(\optexp@nodeA)%
}%
\def\POE@conn@out@o{%
  \psline[style=Beam](\optexp@nodeB)(\oenodeRefB{})%
}%
\def\POE@conn@in@f{%
  \pccurve[%
    angleA=!\POE@dict{/N@\oenodeRefA{} /N@\oenodeRefB{} SlopeAngle},
    angleB=!\POE@dict{/N@\oenodeRefB{} /N@\oenodeRefA{} SlopeAngle},
    style=FiberIn](\oenodeRefA{})(\optexp@nodeA)%
}%
\def\POE@conn@out@f{%
  \pccurve[%
    angleA=!\POE@dict{/N@\oenodeRefA{} /N@\oenodeRefB{} SlopeAngle},
    angleB=!\POE@dict{/N@\oenodeRefB{} /N@\oenodeRefA{} SlopeAngle},
    style=FiberOut](\optexp@nodeB)(\oenodeRefB{})%
}%
\def\POE@conn@in@i{%
  \def\pst@par{style=Beam}
  \begin@OpenObj
    \addto@pscode{%
      [%]
      \pst@optexpdict
        (\oenode{}{}) true GetInternalBeamNodesCompat
        /N@\oenodeRefA{} @GetCenter 
      end
    }%
  \psline@ii
}%
\def\POE@conn@out@i{%
  \def\pst@par{style=Beam}
  \begin@OpenObj
    \addto@pscode{%
      [%]
      \pst@optexpdict
        /N@\oenodeRefB{} @GetCenter
        (\oenode{}{}) true GetInternalBeamNodesCompat
      end
    }%
  \psline@ii
}%
\def\POE@conn@in@a{%
  dup xcheck not {
    \POE@dict{1 GetInternalBeamNodeCompat}
  } if
  exec
}%
\def\POE@conn@in@A{%
  dup xcheck not {
    false \POE@dict{GetInternalBeamNodesCompat} %
  } if
  exec
}%
\def\POE@conn@in@b{%
  dup xcheck not {
    \POE@dict{(N) GetInternalBeamNodeCompat}
  } if
  exec
}%
\def\POE@conn@in@B{%
  dup xcheck not {
    true \POE@dict{GetInternalBeamNodesCompat} %
  } if
  exec
}%
\let\POE@conn@out@a\POE@conn@in@a
\let\POE@conn@out@A\POE@conn@in@B
\let\POE@conn@out@b\POE@conn@in@b
\let\POE@conn@out@B\POE@conn@in@A
\def\drawbeam@compat{%
  \ifPOE@connjoin
    \setkeys+[psset]{optexp}{linejoin=\POE@key@connjoin}%
  \fi
  \addto@pscode{[% ]
    \POE@tempd\space
    \@nameuse{\POE@connOut}
    \POE@tempc\space
    \@nameuse{\POE@connIn}}%
  \psline@ii
\ignorespaces}%
%
%    \end{macrocode}
%
% \section{General purpose macros}
%
% \begin{macro}{\defShiftedNode}
%   This is provided only for backward compatibility, and should be replaced by
%   \cs{nodexn}.
%    \begin{macrocode}
\def\defShiftedNode(#1)(#2)#3{%
  \PackageWarning{pst-optexp}{%
    \string\defShiftedNode\space is deprecated,\MessageBreak
    use \string\nodexn\space(pst-node) instead.}%
  \pst@getcoor{#1}\pst@tempa%
  \pst@getcoor{#2}\pst@tempb%
  \pnode(! \pst@tempb \pst@tempa \POE@dict{VecAdd} \tx@UserCoor){#3}%
}%
%    \end{macrocode}
% \end{macro}
%
% \section{Accessing component nodes} 
% \begin{macro}{\POE@checkcompname}
%    \begin{macrocode}
\def\POE@checkcompname#1{%
  \@expandtwoargs\in@{,#1,}{,\POE@complist,}%
  \ifin@\else
    \PackageError{pst-optexp}{Component '#1' is undefined}
  \fi
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\POE@getlastcompname}
%    \begin{macrocode}
\def\POE@getlastcompname{%
  \expandafter\POE@getlastcompname@i \POE@complist,\relax,\@nil
}%
\def\POE@getlastcompname@i#1,#2,#3\@nil{#1}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\oenode}
%    \begin{macrocode}
\def\oenode#1#2{%
  \POE@str@basicname@prefix%
  \ifx\\#2\\%
    \ifnum9<1\POE@getlastcompname\space%
      \POE@str@basicname@default
      \POE@getlastcompname
    \else
      \POE@getlastcompname
      \POE@str@basicname@sep
    \fi
  \else
    \ifnum9<1#2
      \POE@str@basicname@default
      #2%
    \else
      #2\POE@str@basicname@sep%
    \fi%
  \fi%
  #1%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\oenodeExt}
% The external node which is set with \opt{extnode}.
%    \begin{macrocode}
\def\oenodeExt#1{\oenode{\POE@str@extnode@postfix}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenodeIn}
% The first (input) node of the component.
%    \begin{macrocode}
\def\oenodeIn#1{\oenode{1}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenodeOut}
%    \begin{macrocode}
\def\oenodeOut#1{\oenode{N}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenodeCenter}
%    \begin{macrocode}
\def\oenodeCenter#1{\oenode{Center}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenodeLabel}
%    \begin{macrocode}
\def\oenodeLabel#1{\oenode{Label}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenodeRefA}
%    \begin{macrocode}
\def\oenodeRefA#1{\oenode{A}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenodeRefB}
%    \begin{macrocode}
\def\oenodeRefB#1{\oenode{B}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenodeRotref}
%    \begin{macrocode}
\def\oenodeRotref#1{\oenode{Rotref}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenodeTrefA}
%    \begin{macrocode}
\def\oenodeTrefA#1{\oenode{TrefA}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenodeTrefB}
%    \begin{macrocode}
\def\oenodeTrefB#1{\oenode{TrefB}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenode@RefA}
%    \begin{macrocode}
\def\oenode@RefA#1{\oenode{@A}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenode@RefB}
%    \begin{macrocode}
\def\oenode@RefB#1{\oenode{@B}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenode@TrefA}
%    \begin{macrocode}
\def\oenode@TrefA#1{\oenode{@TrefA}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenode@TrefB}
%    \begin{macrocode}
\def\oenode@TrefB#1{\oenode{@TrefB}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenodeIfc}
%    \begin{macrocode}
\def\oenodeIfc#1#2{%
  \ifnum9<1#1 %
    \oenode{#1}{#2}%
  \else\ifx#1N %
    \oenode{#1}{#2}%
  \else\ifx#1C %
    \oenode{#1}{#2}%
  \else
    \PackageWarning{pst-optexp}{%
      \string\oenodeIfc\space node argument must be\MessageBreak
      integer, 'N', or 'C'.}
  \fi\fi\fi
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenodeBeam}
%    \begin{macrocode}
\def\oenodeBeam#1{%
  \POE@str@basicname@prefix\POE@str@basicname@default Beam%
  \ifx\\#1\\1\else#1\fi
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenodeBeamUp}
%    \begin{macrocode}
\def\oenodeBeamUp#1{%
  \POE@str@basicname@prefix\POE@str@basicname@default BeamUp%
  \ifx\\#1\\1\else#1\fi
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenodeBeamLow}
%    \begin{macrocode}
\def\oenodeBeamLow#1{%
  \POE@str@basicname@prefix\POE@str@basicname@default BeamLow%
  \ifx\\#1\\1\else#1\fi
}%
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
\def\POE@beamvec#1#2{%
  \POE@dict{%
    /prevVec#1\ifx\\#2\\1\else#2\fi\space dup
    currentdict exch known { load exec }{ pop 0 0 } ifelse
  }%
}%
\def\oeBeamVec#1{\POE@beamvec{}{#1}}%
\def\oeBeamVecUp#1{\POE@beamvec{Up}{#1}}%
\def\oeBeamVecLow#1{\POE@beamvec{Low}{#1}}%
%    \end{macrocode}
% \section{Components}
%
%    \begin{macrocode}
\def\POE@useifccode{%
  \POE@Verb{%
    [ \pst@code
    \ifPOE@allowbeaminside true \else false \fi
    \ifPOE@forcebeaminside true \else false \fi
    (\oenode{}{}) {\tx@ScreenCoor}
    NewOptexpComp
  }%
  \gdef\pst@code{}%
}%
\def\begin@CompIfc{%
  \begingroup
}%
\def\end@CompIfc{%
  \addto@pscode{ false }%
  \POE@useifccode
  \endgroup
  \ignorespaces
}%
\def\end@AmbCompIfc{%
  \addto@pscode{ true }%
  \POE@useifccode
  \endgroup
  \ignorespaces
}%
%    \end{macrocode}
% \begin{macro}{\newOptexpComp@}
%    \begin{macrocode}
\def\newOptexpComp@#1#2{%
  \POE@Verb{%
    \tx@NodeScale
    [ #1 #2 
    \ifPOE@allowbeaminside true \else false \fi
    \ifPOE@forcebeaminside true \else false \fi
    (\oenode{}{}) {\tx@ScreenCoor} 
    NewOptexpComp
  }%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\newOptexpComp}
%    \begin{macrocode}
\def\newOptexpComp#1{%
  \newOptexpComp@{#1}{false}%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\newOptexpCompAmb}
%    \begin{macrocode}
\def\newOptexpCompAmb#1{%
  \newOptexpComp@{#1}{true}%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\newOptexpComp@}
%    \begin{macrocode}
\def\newOptexpFiberComp#1{%
  \POE@Verb{%
    \tx@NodeScale
    [ #1 (\oenode{}{}) {\tx@ScreenCoor}
      NewOptexpFiberComp
  }%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\POE@compalias}
%   Components which have a \opt{compname} assigned, must also be available by
%   their component number. Here, all necessary informations (nodes, component
%   dictionary) are referenced such that any information is accessible via
%   numeber or name.
%    \begin{macrocode}
\def\POE@compalias#1#2{%
  \POE@Verb{%
%    \end{macrocode}
% Copy the component dictionary
%    \begin{macrocode}
    /\oenode{}{#1} dup currentdict exch known { 
      load /#2 ED 
    } { 
      pop 
    } ifelse
    (#2) (\oenode{}{#1})
    tx@NodeDict begin
%    \end{macrocode}
% Copy all interface nodes of the component.
%    \begin{macrocode}
      1 {
        3 copy inttostr dup 
        3 1 roll 2 copy NodeName
        currentdict exch known {
          NodeName load 3 1 roll NodeName ED
          1 add
        } {
          pop (N) NodeName load 3 1 roll 
          pop (N) NodeName ED
          pop exit
        } ifelse
      } loop
%    \end{macrocode}
% Copy all other nodes associated with the component (reference nodes, center
% node, label node etc).
%    \begin{macrocode}
      [ (A) (B) (@A) (@B) (Center) (Label) (Rotref) 
        (TrefA) (TrefB) (@TrefA) (@TrefB) (Ext)
      counttomark {
        counttomark 3 add -2 roll 2 copy counttomark 1 add 2 roll
        3 -1 roll dup 4 1 roll NodeName dup 
        currentdict exch known { 
          load 3 1 roll exch NodeName ED 
        } { 
          pop pop pop 
        } ifelse
      } repeat pop pop pop
    end
  }%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\optplane}
%   Define an invisible plane which is used only for ray tracing. The first node
%   is the origin, the second one is the difference vector.
%    \begin{macrocode}
\def\optplane{%
  \@ifnextchar[%]
    {\optplane@i}{\optplane@i[]}%
}%
\def\optplane@i[#1](#2){%
  \pst@getcoor{#2}\POE@tempa
%    \end{macrocode}
% Set the height to 0 to circumvent problems with the NA beeing too low
%    \begin{macrocode}
  \optplate[#1, plateheight=0, linestyle=none]%
    (! \POE@tempa exch 1 sub exch \tx@UserCoor)%
    (! \POE@tempa exch 1 add exch \tx@UserCoor)%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\begin@OptexpObj}
%    \begin{macrocode}
\def\begin@OptexpObj{%
  \global\advance\POE@cnt by 1
  \addbefore@par{compname={}}%
  \pst@killglue
  \begingroup
    \POE@insideobjtrue
    \POE@Verb{InitOptexpComp }%
    \use@par
%    \end{macrocode}
% The \opt{compshift} refers to the $y$-direction, shifting in $x$-direction
% is done by \opt{abspos} or \opt{position}
%    \begin{macrocode}
    \let\POE@key@comp@Yshift\POE@key@compshift%
    \let\POE@key@comp@Xshift\POE@key@compoffset%
    \edef\POE@refnodeA{\oenodeRefA{}}%
    \edef\POE@refnodeB{\oenodeRefB{}}%
    \edef\POE@trefnodeA{\oenodeTrefA{}}%
    \edef\POE@trefnodeB{\oenodeTrefB{}}%
    \def\POE@transformnodes{%
      \POE@transformnode{\oenodeRefA{}}{\oenodeTrefA{}}%
      \POE@transformnode{\oenodeRefB{}}{\oenodeTrefB{}}%
    }%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\begin@OptexpFiberObj}
%    \begin{macrocode}
\let\begin@OptexpFiberObj\begin@OptexpObj
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\begin@OptexpTripole}
%    \begin{macrocode}
\let\POE@disablepos\relax
\def\begin@OptexpTripole{%
  \begin@OptexpObj
%    \end{macrocode}
% for multipoles the default shifting is in $x$-direction
%    \begin{macrocode}
  \def\POE@key@comp@Xshift{\POE@key@compshift\space neg }%
  \let\POE@key@comp@Yshift\POE@key@compoffset
%    \end{macrocode}
% The positioning parameters are disabled, because \opt{compshift} does the job for tripoles.
%    \begin{macrocode}
  \def\POE@disablepos{%
    \let\POE@key@abspos\@empty
    \let\POE@key@position\@empty
  }%
  \POE@positionrefnodes
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\POE@positionrefnodes}
%    \begin{macrocode}
\def\POE@positionrefnodes{%
  \edef\POE@refnodeA{\oenode@RefA{}}%
  \edef\POE@refnodeB{\oenode@RefB{}}%
  \edef\POE@trefnodeA{\oenode@TrefA{}}%
  \edef\POE@trefnodeB{\oenode@TrefB{}}%
  \def\POE@transformnodes{%
    \POE@transformnode{\oenodeRefA{}}{\oenodeTrefA{}}%
    \POE@transformnode{\oenodeRefB{}}{\oenodeTrefB{}}%
    \POE@transformnode{\oenode@RefA{}}{\oenode@TrefA{}}%
    \POE@transformnode{\oenode@RefB{}}{\oenode@TrefB{}}%
  }%
}%
%
% \begin{macro}{\end@OptexpObj}
%    \begin{macrocode}
\def\end@OptexpObj{%
  \ifnum9<1\POE@key@compname\else
    \POE@compalias{\POE@key@compname}{\oenode{}{\the\POE@cnt}}%
  \fi
  \endgroup
  \ignorespaces%
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\end@OptexpDipole}
%    \begin{macrocode}
\let\end@OptexpDipole\end@OptexpObj
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\end@OptexpTripole}
%    \begin{macrocode}
\let\end@OptexpTripole\end@OptexpObj
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\addafter@par}
%   Analog to \cs{addbefore@par} from pstricks.tex, but inserts new options at
%   the end of the current token register.  This can be useful to preset options
%   that are not allowed to be changed by the user.
%    \begin{macrocode}
\def\addafter@par#1{%
  \ifx\pst@par\@empty
    \def\pst@par{#1}%
  \else
    \toks@{#1}%
    \pst@toks\expandafter{\pst@par}%
    \edef\pst@par{\the\pst@toks,\the\toks@}%
  \fi%
}%
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
\def\POE@clwh{CLW \pst@number\psxunit 2 mul div }%
\def\POE@clw{CLW \pst@number\psxunit div }%
\let\POE@restorerefnodes\relax
%    \end{macrocode}
% 
% New high-level macros 
% 1) Allow a compressed notation of all provided elements, as most of the organizing code 
%    is mostly equal.
%
% 2) Provide a rather easy-to-use interface for the user to allow new user-defined elements
%
% \begin{macro}{\newOptexpDipole}
%    \begin{macrocode}
\def\newOptexpDipole{%
  \@ifnextchar[%]
    {\POE@newdipole}{\POE@newdipole[]}%
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\newOptexpDipoleNolabel}
%    \begin{macrocode}
\def\newOptexpDipoleNolabel{%
  \PackageWarning{pst-optexp}{%
    \string\newOptexpDipoleNolabel\space is deprecated,\MessageBreak
    use \string\newOptexpDipole\space instead.}%
  \newOptexpDipole
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\newOptexpTripole}
%    \begin{macrocode}
\def\newOptexpTripole{%
  \@ifnextchar[%]
    {\POE@newtripole}{\POE@newtripole[]}%
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\newOptexpFiberDipole}
%    \begin{macrocode}
\def\newOptexpFiberDipole{%
  \@ifnextchar[%]
    {\POE@newfiberdipole}{\POE@newfiberdipole[]}%
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\POE@newdipole}
%    \begin{macrocode}
\def\POE@newdipole[#1]#2#3{%
  \@ifundefined{#2@i}{%
    \@namedef{#2}{\pst@object{#2}}%
    \expandafter\def\csname #2@i\endcsname(##1)(##2){%
      \@ifnextchar\bgroup%
        {\@nameuse{#2@i@}(##1)(##2)}%
        {\@nameuse{#2@i@}(##1)(##2){}}%
    }%
    \expandafter\def\csname #2@i@\endcsname(##1)(##2)##3{%
      \addbefore@par{#3}%
      \addafter@par{#1}%
      \begin@OptexpObj
        \ifPOE@backlayer
          \POE@regNodes{##1}{##2}
          \POE@extnodealign
        \fi
        \POE@drawcomponent[#2]{##3}{\@nameuse{#2@ii}}
        \ifPOE@backlayer
          \POE@Verb{ (1) (N) (\oenode{}{}) CorrectDipoleIfc }%
          \POE@drawInternalConnections
        \fi
      \end@OptexpDipole
    }%
    \dipole@iimacro{#2}%
  }{%
    \PackageError{pst-optexp}{%
      dipole component '#2' already defined}%
  }%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\POE@newfiberdipole}
%    \begin{macrocode}
\def\POE@newfiberdipole[#1]#2#3{%
  \@ifundefined{#2@i}{%
    \@namedef{#2}{\pst@object{#2}}%
    \expandafter\def\csname #2@i\endcsname(##1)(##2){%
      \@ifnextchar\bgroup%
        {\@nameuse{#2@i@}(##1)(##2)}%
        {\@nameuse{#2@i@}(##1)(##2){}}%
    }%
    \expandafter\def\csname #2@i@\endcsname(##1)(##2)##3{%
      \addbefore@par{#3}%
      \addafter@par{#1}%
      \begin@OptexpFiberObj
        \ifPOE@backlayer
          \POE@regNodes{##1}{##2}
          \POE@extnodealign
        \fi
        \POE@drawcomponent[#2]{##3}{\@nameuse{#2@ii}}
        \ifPOE@backlayer
          \POE@Verb{ (1) (N) (\oenode{}{}) CorrectDipoleIfc }%
          \ifPOE@fiberpreset@
            \POE@drawPresetFibers
          \fi
        \fi
        \end@OptexpDipole
      }%
      \fiberdipole@iimacro{#2}%
   }{%
     \PackageError{pst-optexp}{%
       fiber dipole object '#2' already defined}%
  }%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\POE@newtripole}
% Equivalent to \cs{POE@newdipole} for tripole objects.
%    \begin{macrocode}
\def\POE@newtripole[#1]#2#3{%
  \@ifundefined{#2@i}{%
    \@namedef{#2}{\pst@object{#2}}%
    \expandafter\def\csname #2@i\endcsname(##1)(##2)(##3){%
      \@ifnextchar\bgroup{\@nameuse{#2@i@}(##1)(##2)(##3)}%
                         {\@nameuse{#2@i@}(##1)(##2)(##3){}}%
    }%
    \expandafter\def\csname #2@i@\endcsname(##1)(##2)(##3)##4{%
      \addbefore@par{#3}%
      \addafter@par{ref@angle=180,#1}%
      \begin@OptexpTripole
        \ifPOE@backlayer
          \POE@calcNodes{##1}{##2}{##3}%
          \POE@regNodes{##1}{##3}%
        \fi
        \POE@drawcomponent[#2]{##4}{\@nameuse{#2@ii}}
        \ifPOE@backlayer
          \POE@drawInternalConnections
        \fi
      \end@OptexpTripole
    }%
    \tripole@iimacro{#2}%
  }{%
    \PackageError{pst-optexp}{%
      tripole object '#2' already defined}%
  }%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\dipole@iimacro}
%    \begin{macrocode}
\def\dipole@iimacro#1{%
  \POE@iimacro{#1}{\dipole@nodes}%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fiberdipole@iimacro}
%    \begin{macrocode}
\def\fiberdipole@iimacro#1{%
  \POE@iimacro{#1}{\fiberdipole@nodes}%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\tripole@iimacro}
%    \begin{macrocode}
\def\tripole@iimacro#1{%
  \POE@iimacro{#1}{\tripole@nodes}%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\POE@iimacro}
%    \begin{macrocode}
\def\POE@iimacro#1#2{%
  \@namedef{#1@ii}{%
    \ifPOE@backlayer
      \pnode(0,0){\oenodeCenter{}}%
    \fi
    \@ifundefined{#1@iii}{%
      \ifPOE@backlayer
        \@ifundefined{#1@nodes}{#2}{\@nameuse{#1@nodes}}%
      \fi
      \ifPOE@frontlayer
        \@nameuse{#1@comp}%
      \fi
    }{%
      \ifPOE@backlayer
        \PackageWarning{pst-optexp}{%
          Using #1@iii, please switch to the new\MessageBreak
          interface system.}%
        \@nameuse{#1@iii}%
      \fi
    }%
  }%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\POE@newfiberquadrupole}
%    \begin{macrocode}
\def\optcoupler{\pst@object{optcoupler}}%
\def\optcoupler@i(#1)(#2){%
  \@ifnextchar(%)
    {\optcoupler@@i@(#1)(#2)}%
    {\optcoupler@@i@(#1)(#1)(#2)(#2)}%
}%
\def\optcoupler@@i@(#1)(#2)(#3)(#4){%
  \@ifnextchar\bgroup%
    {\optcoupler@i@(#1)(#2)(#3)(#4)}%
    {\optcoupler@i@(#1)(#2)(#3)(#4){}}%
}%
\def\optcoupler@i@(#1)(#2)(#3)(#4)#5{%
  \begin@OptexpFiberObj
    \ifPOE@backlayer
      \ifx\POE@key@coupleralign\POE@str@top
        \pnode(#1){\oenodeRefA{}}
        \pnode(#3){\oenodeRefB{}}
      \else\ifx\POE@key@coupleralign\POE@str@bottom
        \pnode(#2){\oenodeRefA{}}
        \pnode(#4){\oenodeRefB{}}
      \else
        \pst@getcoor{#1}\POE@tempa%
        \pst@getcoor{#2}\POE@tempb%
        \pnode(!\POE@tempa \POE@tempb 
                \POE@dict{VecAdd 0.5 VecScale}
                \tx@UserCoor){\oenodeRefA{}}
        \pst@getcoor{#3}\POE@tempa%
        \pst@getcoor{#4}\POE@tempb%
        \pnode(!\POE@tempa \POE@tempb 
                \POE@dict{VecAdd 0.5 VecScale}
                \tx@UserCoor){\oenodeRefB{}}
      \fi\fi
    \fi
    \POE@drawcomponent[optcoupler]{#5}{\@nameuse{optcoupler@ii}}
    \ifPOE@backlayer
      \POE@Verb{%
        (1) (3) (\oenode{}{}) CorrectDipoleIfc 
        (2) (N) (\oenode{}{}) CorrectDipoleIfc 
      }%
      \ifPOE@fiberpreset@
        \ifPOE@fiberpresetin@
          \ifPOE@fiberpresetin@top
            \drawfiber@{FiberIn1}[stopnode=1]{(#1)}%
                                             {\POE@key@compname}
          \fi
          \ifPOE@fiberpresetin@bottom
            \drawfiber@{FiberIn2}[stopnode=2]{(#2)}%
                                             {\POE@key@compname}
          \fi
        \fi
        \ifPOE@fiberpresetout@
          \ifPOE@fiberpresetout@top
            \drawfiber@{FiberOut1}[startnode=3]{\POE@key@compname}%
                                              {(#3)}
          \fi
          \ifPOE@fiberpresetout@bottom
            \drawfiber@{FiberOut2}[startnode=N]{\POE@key@compname}%
                                               {(#4)}
          \fi
        \fi
      \fi
    \fi
  \end@OptexpObj
}%
\fiberdipole@iimacro{optcoupler}%
%    \end{macrocode}
% \end{macro}
% 
% 
% \begin{macro}{\wdmsplitter}
%    \begin{macrocode}
\def\wdmsplitter{\pst@object{wdmsplitter}}%
\def\wdmsplitter@i(#1)(#2){%
  \@ifnextchar(%)
    {\wdmsplitter@@i@(#1)(#2)}%
    {\wdmsplitter@@i@(#1)(#2)(#2)}%
}%
\def\wdmsplitter@@i@(#1)(#2)(#3){%
  \@ifnextchar\bgroup%
    {\wdmsplitter@i@(#1)(#2)(#3)}%
    {\wdmsplitter@i@(#1)(#2)(#3){}}%
}%
\def\wdmsplitter@i@(#1)(#2)(#3)#4{%
  \begin@OptexpFiberObj
    \ifPOE@backlayer
      \pnode(#1){\oenodeRefA{}}
      \ifx\POE@key@coupleralign\POE@str@top
         \pnode(#2){\oenodeRefB{}}
      \else\ifx\POE@key@coupleralign\POE@str@bottom
         \pnode(#3){\oenodeRefB{}}
      \else
         \pst@getcoor{#2}\POE@tempa%
         \pst@getcoor{#3}\POE@tempb%
         \pnode(!\POE@tempa \POE@tempb 
                 \POE@dict{VecAdd 0.5 VecScale}
                 \tx@UserCoor){\oenodeRefB{}}
      \fi\fi
    \fi
    \POE@drawcomponent[wdmsplitter]{#4}\wdmsplitter@ii
    \ifPOE@backlayer
      \POE@Verb{%
        (1) (2) (\oenode{}{}) CorrectDipoleIfc 
        (1) (N) (\oenode{}{}) CorrectDipoleIfc 
      }%
      \ifPOE@fiberpreset@
        \ifPOE@fiberpresetin@
          \drawfiber@{FiberIn}[stopnode=1]{(#1)}{\POE@key@compname}
        \fi
        \ifPOE@fiberpresetout@
          \ifPOE@fiberpresetout@top
            \drawfiber@{FiberOut1}[startnode=2]%
              {\POE@key@compname}{(#2)}
          \fi
          \ifPOE@fiberpresetout@bottom
            \drawfiber@{FiberOut2}[startnode=N]%
              {\POE@key@compname}{(#3)}
          \fi
        \fi
      \fi
    \fi
  \end@OptexpObj
}%
\fiberdipole@iimacro{wdmsplitter}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\wdmcoupler}
%    \begin{macrocode}
\def\wdmcoupler{\pst@object{wdmcoupler}}%
\def\wdmcoupler@i(#1)(#2){%
  \@ifnextchar(%)
    {\wdmcoupler@@i@(#1)(#2)}%
    {\wdmcoupler@@i@(#1)(#1)(#2)}%
}%
\def\wdmcoupler@@i@(#1)(#2)(#3){%
  \@ifnextchar\bgroup%
    {\wdmcoupler@i@(#1)(#2)(#3)}%
    {\wdmcoupler@i@(#1)(#2)(#3){}}%
}%
\def\wdmcoupler@i@(#1)(#2)(#3)#4{%
  \begin@OptexpFiberObj
    \ifPOE@backlayer
      \pnode(#3){\oenodeRefB{}}
      \ifx\POE@key@coupleralign\POE@str@top
         \pnode(#1){\oenodeRefA{}}
      \else\ifx\POE@key@coupleralign\POE@str@bottom
         \pnode(#2){\oenodeRefA{}}
      \else
         \pst@getcoor{#1}\POE@tempa%
         \pst@getcoor{#2}\POE@tempb%
         \pnode(!\POE@tempa \POE@tempb 
                 \POE@dict{VecAdd 0.5 VecScale}
                 \tx@UserCoor){\oenodeRefA{}}
      \fi\fi
    \fi
    \POE@drawcomponent[wdmcoupler]{#4}\wdmcoupler@ii
    \ifPOE@backlayer 
      \POE@Verb{%
        (1) (N) (\oenode{}{}) CorrectDipoleIfc 
        (2) (N) (\oenode{}{}) CorrectDipoleIfc
      }%
      \ifPOE@fiberpreset@
        \ifPOE@fiberpresetout@
          \drawfiber@{FiberOut}[startnode=N]{\POE@key@compname}{(#3)}
        \fi
        \ifPOE@fiberpresetin@
          \ifPOE@fiberpresetin@top
            \drawfiber@{FiberIn1}[stopnode=1]{(#1)}{\POE@key@compname}
          \fi 
          \ifPOE@fiberpresetin@bottom
            \drawfiber@{FiberIn2}[stopnode=2]{(#2)}{\POE@key@compname}
          \fi
        \fi
      \fi
    \fi
  \end@OptexpObj
}%
\fiberdipole@iimacro{wdmcoupler}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\optcirculator}
%    \begin{macrocode}
\def\optcirculator{\pst@object{optcirculator}}%
\def\optcirculator@i(#1)(#2)(#3){%
  \@ifnextchar\bgroup%
    {\optcirculator@i@(#1)(#2)(#3)}%
    {\optcirculator@i@(#1)(#2)(#3){}}%
}%
\def\optcirculator@i@(#1)(#2)(#3)#4{%
  \addafter@par{ref@angle=180}%
  \begin@OptexpFiberObj
    \ifPOE@backlayer
      \POE@regNodes{#1}{#2}
      \ifx\POE@key@position\@empty
        \ifx\POE@key@abspos\@empty
          \POE@positionrefnodes
          \pst@getcoor{#1}\POE@tempa%
          \pst@getcoor{#2}\POE@tempc%
          \pst@getcoor{#3}\POE@tempb%
          \pnode(! \POE@dict{%
            \POE@tempa \tx@UserCoor 2 copy 2 copy 
            \POE@tempc \tx@UserCoor 4 2 roll @ABVect
            2 copy 2 copy 10 4 roll
            \POE@tempb \tx@UserCoor 6 -2 roll @ABVect
            4 2 roll tx@EcldDict begin Project end VecAdd
            2 copy 6 -2 roll -0.5 VecScale VecAdd
          }){\oenode@RefA{}}%
          \pnode(! \POE@dict{4 2 roll 0.5 VecScale VecAdd})%
            {\oenode@RefB{}}%
        \fi
      \fi
    \fi
    \POE@drawcomponent[optcirculator]{#4}\optcirculator@ii
    \ifPOE@backlayer
      \ifPOE@fiberpreset@
        \ifPOE@fiberpresetin@top
          \drawfiber@{FiberIn}[stopnode=1]{(#1)}{\POE@key@compname}
        \fi
        \ifPOE@fiberpresetout@
          \ifPOE@fiberpresetout@top
            \drawfiber@{FiberOut1}[startnode=N]%
              {\POE@key@compname}{(#2)}
          \fi
          \ifPOE@fiberpresetout@bottom
            \drawfiber@{FiberOut2}[startnode=2, fiberalign=center]%
              {\POE@key@compname}{(#3)}
          \fi
        \fi
      \fi
    \fi
  \end@OptexpObj
}%
\fiberdipole@iimacro{optcirculator}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\optcirculator}
%    \begin{macrocode}
\def\fiberbox{\pst@object{fiberbox}}%
\def\fiberbox@i(#1)(#2){%
  \@ifnextchar(%)
    {\fiberbox@@i@(#1)(#2)}%
    {\fiberbox@@i@(#1)(#2)()()}%
}%
\def\fiberbox@@i@(#1)(#2)(#3)(#4){%
  \@ifnextchar\bgroup%
    {\fiberbox@i@(#1)(#2)(#3)(#4)}%
    {\fiberbox@i@(#1)(#2)(#3)(#4){}}%
}%
\def\fiberbox@i@(#1)(#2)(#3)(#4)#5{%
  \begin@OptexpFiberObj
    \ifnum\POE@key@fiberboxcountin=1
      \ifnum\POE@key@fiberboxcountout=1
        \ifdim\POE@key@fiberboxheight pt=0pt
          \PackageError{pst-optexp}{%
            Cannot determine height of 1x1 fiberbox automatically, 
            use fiberboxheight}%
        \fi
      \fi
    \fi
    \ifPOE@backlayer
      \ifx\\#3#4\\%
        \POE@regNodes{#1}{#2}
        \POE@Verb{/@@inht 0 def /@@outht 0 def}%
      \else
        \pst@getcoor{#1}\POE@tempa%
        \pst@getcoor{#2}\POE@tempb%
        \pst@getcoor{#3}\POE@tempc%
        \pst@getcoor{#4}\POE@tempd%
        \pnode(!\POE@tempa \POE@tempb 
                \POE@dict{VecAdd 0.5 VecScale}
                \tx@UserCoor){\oenodeRefA{}}
        \pnode(!\POE@tempc \POE@tempd
                \POE@dict{VecAdd 0.5 VecScale}
                \tx@UserCoor){\oenodeRefB{}}
        \POE@Verb{%
          gsave
            STV CP T 
            /N@\oenodeRefA{} @GetCenter
            /N@\oenodeRefB{} @GetCenter @ABVect NormalizeVec 
            90 matrix rotate dtransform 2 copy
            \POE@tempa \POE@tempb @ABVect
            \tx@UserCoor DotProd abs 3 1 roll
            \POE@tempc \POE@tempd @ABVect 
            \tx@UserCoor DotProd abs 
          grestore
          /@@outht ED /@@inht ED
        }%
      \fi
    \fi
    \POE@drawcomponent[fiberbox]{#5}\fiberbox@ii
    \ifPOE@backlayer
      \ifx\\#3#4\\%
%    \end{macrocode}
% Connect only, if the fiberbox has a single related interface node.
%    \begin{macrocode}
        \ifPOE@fiberpreset@
          \ifnum\POE@key@fiberboxcountin=1
            \ifPOE@fiberpresetin@
              \drawfiber@{FiberIn}{(#1)}{\POE@key@compname}
            \fi
          \fi
          \ifnum\POE@key@fiberboxcountout=1
            \ifPOE@fiberpresetout@
              \drawfiber@{FiberOut}{\POE@key@compname}{(#2)}
            \fi
          \fi
        \fi
      \else
%    \end{macrocode}
% If four nodes are specified, connect all of them with the respective interface
% nodes they are aligned to.
%    \begin{macrocode}
        \ifPOE@fiberpreset@
          \ifPOE@fiberpresetin@
            \ifPOE@fiberpresetin@top
              \drawfiber@{FiberIn1}{(#1)}{\POE@key@compname}
            \fi
            \ifPOE@fiberpresetin@bottom
              \drawfiber@{FiberIn2}{(#2)}{\POE@key@compname}
            \fi
          \fi
          \ifPOE@fiberpresetout@
            \ifPOE@fiberpresetout@top
              \drawfiber@{FiberOut1}{\POE@key@compname}{(#3)}
            \fi
            \ifPOE@fiberpresetout@bottom
              \drawfiber@{FiberOut2}{\POE@key@compname}{(#4)}
            \fi
          \fi
        \fi
      \fi
    \fi
  \end@OptexpObj
}%
\fiberdipole@iimacro{fiberbox}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\POE@calcNodes}
%   Some of the components need three points to be positioned. 
%   These are:
%
% \begin{enumerate}
% \item starting point of the beam (in the PS-Code: (XA,YA)) 
% \item reflection point on the surface (XG, YG) 
% \item end point (XB,YB)
%  \end{enumerate}     
%
%  With these three points \cs{poe@calcNodes} calculates two new points 'tempNode@A' 
%  and 'tempNode@B', between which the component is placed by the macro 
%  \cs{poe@drawcomponent} in the way, that 'angle of incidence' == 'angle of deflection'
%  regarding the reflection surface (mirror, diagonal of the beamsplitter, 
%  grid etc.)
%    \begin{macrocode}
\def\POE@calcNodes#1#2#3{{%
  \pst@getcoor{#1}\POE@tempa%
  \pst@getcoor{#2}\POE@tempb%
  \pst@getcoor{#3}\POE@tempc%
  \pnode(! \POE@dict{%
    \POE@tempa \tx@UserCoor
    \POE@tempc \tx@UserCoor
    \POE@tempb \tx@UserCoor
    calcNodes
    X@A Y@A}){\oenode@RefA{}}%
  \pnode(! \POE@dict{X@B Y@B}){\oenode@RefB{}}%
}\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\POE@regNodes}
% If a macro needs only two points, they are equivalent to 
% 'tempNode@A' and 'tempNode@B'. But for easier implementation of other 
% macros the given points are assigned to the temporary nodes.
%    \begin{macrocode}
\def\POE@regNodes#1#2{%
  \pnode(#1){\oenodeRefA{}}
  \pnode(#2){\oenodeRefB{}}
  \POE@Verb{%
    /@xref \POE@key@extnode@xref\space def 
    /@yref \POE@key@extnode@yref\space def
  }%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\POE@extnodealign}
%    \begin{macrocode}
\def\POE@extnodealign{%
  \ifx\POE@key@extnodealign\POE@str@absolute
    \POE@Verb{%
      /N@\oenodeRefA{} @GetCenter /N@\oenodeRefB{} @GetCenter
      @ABVect exch
      dup 0 gt 3 1 roll 0 eq exch 0 lt and or
      { /RefFac -1 def } if
    }%
  \fi
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\POE@pnode@shiftedrot}
% Define a new node \#3 shifted by (\#1) relative to existing node \#2.
% Aditionally rotate the new node by \#4 degree around existing node as origin.
%    \begin{macrocode}
\def\POE@pnode@shiftedrot(#1)#2#3#4{%
  \pst@getcoor{#1}\POE@temp%
  \pnode(!%
    \POE@temp /YDiff ED /XDiff ED %
    \pst@nodedict /N@#2 load GetCenter end /YShifted ED /XShifted ED
    /rot@angle #4 \POE@key@labelrefangle\space add def
    /XDiff@Rot rot@angle cos XDiff mul rot@angle sin YDiff mul add def
    /YDiff@Rot rot@angle cos YDiff mul rot@angle sin XDiff mul sub def
    XShifted XDiff@Rot add YShifted YDiff@Rot add neg \tx@UserCoor
  ){#3}%
  \psset[optexp]{ref@angle=0}
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\POE@nlput}
%   We cannot use \cs{nlput} from \opt{pst-node}, because that does not work
%   correctly for negative distances together with \opt{nrot=:U}, which happens
%   for \opt{position=start}.
%    \begin{macrocode}
\def\POE@nlput{\pst@object{POE@nlput}}
\def\POE@nlput@i(#1)(#2)#3#4{%
  \begin@SpecialObj
  \POE@LDNode(#1)(#2){#3}
  \pcline[linestyle=none,fillstyle=none, arrows=-, ArrowInside=-](temp@nlputA)(temp@nlputB)%
  \ncput[npos=0.5]{#4}%
  \end@SpecialObj}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\POE@LDNode}
%    \begin{macrocode}
\def\POE@LDNode(#1)(#2)#3{%
  \pst@getcoor{#1}\pst@tempA%
  \pst@getcoor{#2}\pst@tempB%
  \pnode(!
    \pst@tempA \tx@UserCoor /YA ED /XA ED
    \pst@tempB \tx@UserCoor /YB ED /XB ED
    /dx XB XA sub def
    /dy YB YA sub def
    /angle dy dx Atan def
    XA #3 1 sub angle cos mul add 
    YA #3 1 sub angle sin mul add ){temp@nlputA}%
  \pnode(!
    \pst@tempA \tx@UserCoor /YA ED /XA ED
    \pst@tempB \tx@UserCoor /YB ED /XB ED
    /dx XB XA sub def
    /dy YB YA sub def
    /angle dy dx Atan def
    XA #3 1 add angle cos mul add 
    YA #3 1 add angle sin mul add ){temp@nlputB}%
}
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\POE@putlabelrelative}
% Used to put the label for labelref=relative
%    \begin{macrocode}
\def\POE@putlabelrelative#1{%
  \nput[labelsep=0]{\POE@key@labelangle}%
       {\oenodeLabel{}}%
       {\rput[\POE@key@labelalign](0,0){\POE@key@labelstyle #1}}%
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\POE@putcomp}
%   Place the component in argument \#1 and define a new node
%   \oenodeLabel{} for positioning of the label.
%    \begin{macrocode}
\def\POE@putcomp#1{%
   \rput(! \POE@key@comp@Xshift\space\POE@key@comp@Yshift){%
     \pnode(! \POE@dict{
       \POE@key@rotate@xref\space
       \POE@key@rotate@yref\space
       DefineExtNode}){\oenodeRotref{}}%
     \ifdim\POE@key@angle pt=0pt
        #1%
        \POE@pnode@shiftedrot(0,\POE@key@labeloffset)%
                             {\oenodeCenter{}}%
                             {\oenodeLabel{}}%
                             {\POE@key@labelangle}%
     \else
        \psrotate(\oenodeRotref{}){\POE@key@angle}{%
          #1%
          \POE@pnode@shiftedrot(0,\POE@key@labeloffset)%
                               {\oenodeCenter{}}%
                               {\oenodeLabel{}}%
                               {\POE@key@labelangle}%
        }%
     \fi%
   }%
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\POE@putlabel}
% Positioning of the label depending on the reference coordinates.
% Needs possibly a previously defined node \cs{oenodeLabel} which
% marks exactly the position of the label relative to the component.
% This is defined by calling \cs{poe@putcomp}.
%    \begin{macrocode}  
\def\POE@putlabel#1{%
  \def\POE@temp{#1}%
%    \end{macrocode}
% Put the label only if it's not empty.
%    \begin{macrocode}
  \ifx\POE@temp\@empty
%    \end{macrocode}
% Place the correct 'global' label node when the label is empty.
%    \begin{macrocode}
    \ifx\POE@key@labelref\POE@str@labelref@global
      \nput[labelsep=\POE@key@labeloffset]%
        {\POE@key@labelangle}%
        {\oenodeCenter{}}%
        {\pnode(0,0){\oenodeLabel{}}}%
    \fi
  \else
%    \end{macrocode}
% For \opt{global} positioning, the label is placed in global coordinate system
% with respect to the center node.
%    \begin{macrocode}
  \ifx\POE@key@labelref\POE@str@labelref@global
    \nput[labelsep=\POE@key@labeloffset]%
      {\POE@key@labelangle}%
      {\oenodeCenter{}}%
      {\pnode(0,0){\oenodeLabel{}}%
       \rput[\POE@key@labelalign](0,0){\POE@key@labelstyle\oelabel{#1}}}%
%    \end{macrocode}
% Rotate the label node together with the component, but do not rotate the label
% text itself.
%    \begin{macrocode}
  \else\ifx\POE@key@labelref\POE@str@labelref@relgrav
    \rput[\POE@key@labelalign](\oenodeLabel{}){%
      \POE@key@labelstyle\oelabel{#1}}%
%    \end{macrocode}
% Rotate label node and label text with the component.
%    \begin{macrocode}
  \else\ifx\POE@key@labelref\POE@str@relative
    \begingroup
%    \end{macrocode}
% Redefine InitNC only for positioning of the label with labelref=relative
%    \begin{macrocode}
    \pst@def{InitNC}< % kindly contributed by Herbert Voss
      /b ED /a ED
      /NodeSepTypeB ED /NodeSepTypeA ED
      /NodeSepB ED /NodeSepA ED
      /OffsetB ED /OffsetA ED
      tx@NodeDict a known tx@NodeDict b known and dup {
        /NodeA a load def /NodeB b load def
        NodeA GetCenter NodeB GetCenter
        4 copy exch 4 -1 roll 2 copy gt
          { pop pop pop pop /yB ED /xB ED /yA ED /xA ED }
          { eq 3 1 roll lt and 
              { /yB ED /xB ED /yA ED /xA ED} 
              { /yA ED /xA ED /yB ED /xB ED} ifelse
          } ifelse
      } if >%
      \ncline[linestyle=none,fillstyle=none, npos=, arrows=-, ArrowInside=-]%
             {\POE@trefnodeA}{\POE@trefnodeB}%
      \ifx\POE@key@position\@empty
        \ifx\POE@key@abspos\@empty
          \ncput[nrot=:U,npos=]{\POE@putlabelrelative{\oelabel{#1}}}%
        \else
          \POE@nlput[nrot=:U](\POE@trefnodeA)(\POE@trefnodeB)%
            {\POE@key@abspos}{\POE@putlabelrelative{\oelabel{#1}}}%
        \fi
      \else
        \ncput[nrot=:U, npos=\POE@key@position]%
          {\POE@putlabelrelative{\oelabel{#1}}}%
      \fi
    \endgroup
  \fi\fi\fi
  \fi
}%
%    \end{macrocode}
% \end{macro}
% 
% \subsection{Free-ray components}
%
% Define all free-ray dipoles
%    \begin{macrocode}
\newOptexpDipole{lens}{}%
\newOptexpDipole{pinhole}{}%
\newOptexpDipole{crystal}{}%
\newOptexpDipole{polarization}{}%
\newOptexpDipole{optbox}{}%
\newOptexpDipole{optplate}{}%
\newOptexpDipole{optretplate}{}%
\newOptexpDipole[endbox]{optdetector}{}%
\newOptexpDipole{optdiode}{allowbeaminside=false}%
\newOptexpDipole{doveprism}{}%
\newOptexpDipole{glanthompson}{}%
%    \end{macrocode}
% 
% Define all free-ray tripoles
%    \begin{macrocode}
\newOptexpTripole{mirror}{}%
\newOptexpTripole[ref@angle=-135]{beamsplitter}{}%
\newOptexpTripole{optgrating}{}%
\def\optgrid{%
  \PackageWarning{pst-optexp}{%
    \string\optgrid\space is deprecated,\MessageBreak
    use \string\optgrating\space instead.}%
  \optgrating%
}%
\newOptexpTripole[ref@angle=-135]{pentaprism}{}%
\newOptexpTripole[ref@angle=-135]{rightangleprism}{}%
\newOptexpTripole[ref@angle=-135]{optprism}{}%
%    \end{macrocode}
%
% \begin{macro}{\optdipole}
%    \begin{macrocode}
\def\optdipole{\pst@object{optdipole}}
\def\optdipole@i(#1)(#2)#3{%
  \@ifnextchar\bgroup%
    {\optdipole@i@(#1)(#2){#3}}%
    {\optdipole@i@(#1)(#2){#3}{}}%
}%
\def\optdipole@i@(#1)(#2)#3#4{%
   \begin@OptexpObj
      \ifPOE@backlayer
        \POE@regNodes{#1}{#2}
        \POE@extnodealign
      \fi
      \POE@drawcomponent[optdipole]{#4}{%
        \ifPOE@backlayer
          \pnode(!\POE@dict{@@x0 @@y0}){\oenodeCenter{}}%
          \dipole@nodes
        \fi
        \ifPOE@frontlayer
          #3
        \fi
      }%
      \ifPOE@backlayer
        \POE@drawInternalConnections
      \fi
   \end@OptexpObj
}%
%    \end{macrocode}
% \end{macro}
%  
% \begin{macro}{\optdipole@ref}
%    \begin{macrocode}
\def\optdipole@ref{%
  \POE@setref{%
    /@@x \POE@key@optdipolewidth\space 0.5 mul def
    /@@y \POE@key@optdipoleheight\space 0.5 mul def
  }%
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\opttripole}
%    \begin{macrocode}
\def\opttripole{\pst@object{opttripole}}
\def\opttripole@i(#1)(#2)(#3)#4{%
  \@ifnextchar\bgroup%
    {\opttripole@i@(#1)(#2)(#3){#4}}%
    {\opttripole@i@(#1)(#2)(#3){#4}{}}%
}%
\def\opttripole@i@(#1)(#2)(#3)#4#5{%
  \addafter@par{ref@angle=180}
  \begin@OptexpTripole
    \ifPOE@backlayer   
      \POE@calcNodes{#1}{#2}{#3}%
      \POE@regNodes{#1}{#3}%
    \fi
    \POE@drawcomponent{#5}{%
      \ifPOE@backlayer
        \tripole@nodes
      \fi
      \ifPOE@frontlayer
        #4
      \fi
    }%
    \ifPOE@backlayer
      \POE@drawInternalConnections
    \fi
  \end@OptexpTripole
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\fibercollimator}
%    \begin{macrocode}
\def\fibercollimator{\pst@object{fibercollimator}}
\def\fibercollimator@i(#1)(#2){%
   \def\POE@tempa{#1}%
   \def\POE@tempb{#2}%
   \def\POE@tempc{}%
   \def\POE@tempd{}%
   \@ifnextchar(%)
     {\fibercollimator@ii}{\fibercollimator@iv}%
}%
\def\fibercollimator@ii(#1){%
   \def\POE@tempc{#1}%
   \@ifnextchar(%)
     {\fibercollimator@iii}{\fibercollimator@iv}%
}%
\def\fibercollimator@iii(#1){%
   \def\POE@tempd{#1}%
   \fibercollimator@iv
}%
\def\fibercollimator@iv{%
  \@ifnextchar\bgroup{\fibercollimator@v}{\fibercollimator@v{}}%
}%
\def\fibercollimator@v#1{%
  \addbefore@par{allowbeaminside=false}%
  \begin@OptexpFiberObj
    \ifPOE@backlayer
      \POE@regNodes{\POE@tempa}{\POE@tempb}%
      \POE@extnodealign
    \fi
    \POE@drawcomponent[fibercollimator]{#1}{%
       \pnode(0,0){\oenodeCenter{}}%
       \ifPOE@backlayer
         \fibercollimator@nodes
       \fi
       \ifPOE@frontlayer
         \fibercollimator@comp
       \fi
    }%
    \ifPOE@backlayer
      \ifPOE@beam
        \drawbeam{(\oenodeRefA{})}{\POE@key@compname}
      \fi
      \ifPOE@fiberpreset@
        \ifPOE@fiberpresetout@
          \ifx\@empty\POE@tempc
            \drawfiber{\POE@key@compname}{(\oenodeRefB{})}
          \else\ifx\@empty\POE@tempd
            \psbezier[style=FiberOut](\oenodeOut{})(\POE@tempb)%
                                     (\POE@tempb)(\POE@tempc)%
          \else
            \psbezier[style=FiberOut](\oenodeOut{})(\POE@tempb)%
                                     (\POE@tempc)(\POE@tempd)%
          \fi\fi
        \fi
      \fi
    \fi
  \end@OptexpObj
}%
%    \end{macrocode}
% \end{macro}
% 
% Define all fiber dipoles
%    \begin{macrocode}
\newOptexpFiberDipole{optfiber}{newOptComp={}}
\newOptexpFiberDipole{optamp}{}
\newOptexpFiberDipole{optmzm}{}
\newOptexpFiberDipole{optfilter}{allowbeaminside=false}
\newOptexpFiberDipole{polcontrol}{}
\newOptexpFiberDipole{optisolator}{}
\newOptexpFiberDipole{optfiberpolarizer}{}
\newOptexpFiberDipole{optswitch}{}
\newOptexpFiberDipole{fiberdelayline}{}
%    \end{macrocode}
%
% \begin{macro}{\POE@drawcomponent}
% This macro is called by every unit
% The first parameter contains the label, the second one the drawing code
%    \begin{macrocode}
\def\POE@drawcomponent{%
  \@ifnextchar[%]
    {\POE@drawcomponent@i}{\POE@drawcomponent@i[]}%
}%
\def\POE@drawcomponent@i[#1]#2#3{%
  \def\POE@comp{%
    #3%
    \ifx\POE@key@extnode\@empty\else
      \ifPOE@backlayer
        \pnode(! \POE@dict{
          \POE@key@extnode@xref\space
          \POE@key@extnode@yref\space
          DefineExtNode}){\oenodeExt{}}%
        \POE@Verb{%
          tx@NodeDict begin /N@\oenodeExt{} load
          \ifnum9<1\POE@key@compname
            /N@ExtNode 
          \else
            /N@\POE@key@compname ExtNode 
          \fi
          ED end 
        }%
      \fi
    \fi
  }%
  \ifx\\#1\\\else
    \@ifundefined{#1@ref}{}{\@nameuse{#1@ref}}%
  \fi
  \begingroup
  \ifPOE@endbox
    \psset[optexp]{abspos={%
      \POE@dict{%
        /N@\POE@refnodeA\space @GetCenter \tx@UserCoor 
        /N@\POE@refnodeB\space @GetCenter \tx@UserCoor 
        @ABDist @@x0 @@x add add 
      }%
    }}%
  \else\ifPOE@startbox
    \psset[optexp]{abspos={\POE@dict{ @@x0 neg @@x sub }}}%
  \fi\fi
  \POE@disablepos
  \ncline[linestyle=none,fillstyle=none,npos=,arrows=-,ArrowInside=-]%
    {\POE@refnodeA}{\POE@refnodeB}%
%    \end{macrocode}
% Positioning of the component
%    \begin{macrocode}
    \psset{style=OptComp}%
%    \end{macrocode}
% linestyle to use, if component should be marked as optional
%    \begin{macrocode}
    \ifPOE@component@optional
      \psset{style=OptionalStyle}%
    \fi
%    \end{macrocode}
% If parameter \opt{position} is given, use it for \opt{npos}.
%    \begin{macrocode}
    \ifx\POE@key@abspos\@empty
%    \end{macrocode}
% Then check if absolute positioning with \opt{abspos} is wanted.
%    \begin{macrocode}
      \ifx\POE@key@position\@empty
        \ncput[nrot=:U,npos=]{\POE@putcomp{\POE@comp}}%
      \else
        \ncput[nrot=:U,npos=\POE@key@position]{\POE@putcomp{\POE@comp}}%
      \fi
    \else
      \POE@nlput[nrot=:U](\POE@refnodeA)(\POE@refnodeB)%
        {\POE@key@abspos}{\POE@putcomp{\POE@comp}}%
    \fi
  \endgroup
  \ifPOE@backlayer
    \POE@transformnodes
  \fi
  \ifPOE@frontlayer
    \POE@putlabel{#2}%
  \fi
%    \end{macrocode}
% Show some special dots for debugging
%    \begin{macrocode}
  \ifPOE@debug@showoptdots
    \ifPOE@frontlayer
      \psdot[linecolor=red](\oenodeCenter{})
      \psdot[linecolor=red, dotstyle=x, dotscale=1.5](\oenodeLabel{})
      \psdot[linecolor=black](\oenodeRefA{})
      \psdot[linecolor=black](\oenodeRefB{})
      \psdot[linecolor=black, dotstyle=x, 
             dotscale=1.5](\oenodeTrefA{})
      \psdot[linecolor=black, dotstyle=x, 
             dotscale=1.5](\oenodeTrefB{})
    \fi
  \fi
  \ifPOE@debug@showifcnodes
    \ifPOE@frontlayer
      \POE@ifcnodes[style=IfcNodeStyle]
    \fi
  \fi
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{POE@setref}
%    \begin{macrocode}
\let\POE@setref\POE@Verb
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{POE@transformnode}
%   Transform node \opt{\#1} according to the positioning parameters
%   (\opt{compshift}, \opt{position}, and \opt{abspos}) with respect to the
%   rotation reference node and define it as \opt{\#2}.
%    \begin{macrocode}
\def\POE@transformnode#1#2{%
  \pnode(!
    \POE@dict{%
      /N@\oenodeRotref{} @GetCenter 2 copy
      /N@#1 @GetCenter 
      \POE@key@comp@Xshift\space\POE@key@comp@Yshift\space
      \tx@ScreenCoor VecAdd 4 2 roll @ABVect 
      \POE@key@angle\space matrix rotate dtransform VecAdd
      \tx@UserCoor
    }){#2}%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\POE@ifcnodes}
%    \begin{macrocode}
\def\POE@ifcnodes{\pst@object{POE@ifcnodes}}
\def\POE@ifcnodes@i{%
  \begin@SpecialObj%
  \solid@star%
  \addto@pscode{
    \psk@dotsize
    \@nameuse{psds@\psk@dotstyle}
    \POE@dict{[ (\oenode{}{}) false GetInternalBeamNodes %]
      counttomark 2 idiv { Dot } repeat
      pop}
    }%
  \end@SpecialObj
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{POE@extnodes}
%    \begin{macrocode}
\def\POE@extnodes{\pst@object{POE@extnodes}}
\def\POE@extnodes@i#1{%
  \begin@SpecialObj
    \let\POE@setref\addto@pscode
    \addto@pscode{\pst@optexpdict InitOptexpComp }
    \@ifundefined{#1@ref}{}{\@nameuse{#1@ref}}%
    \solid@star%
    \addto@pscode{
      \psk@dotsize
      \@nameuse{psds@\psk@dotstyle}
      @@x 0 eq { [0] }{ [ @@x neg 0 @@x ] } ifelse
      {
        @@y 0 eq { [0] }{ [@@y neg 0 @@y ] } ifelse
        {
          exch dup 3 1 roll
          @@x0 add exch @@y0 add \tx@ScreenCoor
          /\oenode{}{} load begin CompMtrx end transform CM itransform
          Dot
        } forall
        pop
      } forall
      end
    }%
  \end@SpecialObj
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\tripole@nodes}
%    \begin{macrocode}
\def\tripole@nodes{%
  \newOptexpComp{{0 0} {1 0} @@x neg @@x refl {PlainIfc} 1}%
  \pnode(! \POE@dict{@@y0 @@x0}){\oenodeCenter{}}
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\dipole@nodes}
%    \begin{macrocode}
\def\dipole@nodes{%
  \newOptexpComp{%
    {@@x0 @@x sub 0} {0 1} @@y0 @@y sub @@y0 @@y add trans {PlainIfc} 
    @@x 0 eq not {
      {@@x0 @@x add 0} {0 1} @@y0 @@y sub @@y0 @@y add trans {PlainIfc}
    } if \POE@key@n }%
  \pnode(! \POE@dict{@@x0 @@y0}){\oenodeCenter{}}
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{fiberdipole@nodes}
%    \begin{macrocode}
\def\fiberdipole@nodes{%
  \newOptexpFiberComp{%
    {@@x0 @@x sub 0}
    @@x 0 eq not {
      {@@x0 @@x add 0}
    } if }%
  \pnode(! \POE@dict{@@x0 @@y0}){\oenodeCenter{}}
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \subsection{Free-ray components}
%
% \subsubsection{mirror}
%
% \begin{macro}{\mirror@ref}
%    \begin{macrocode}
\def\mirror@ref{%
  \ifdim\POE@key@mirrorradius pt=0pt
    \ifx\POE@key@mirrortype\POE@str@mirrortype@piezo
      \POE@setref{/@@y0 \pst@number\psyunit def}%
      \bgroup
        \psset{style=PiezoMirror}%
        \POE@setref{%
          \pst@number\psyunit @@y0 div 
          \POE@key@mirrorwidth\space 0.5 mul mul 2.5 div /@@y0 ED
        }%
      \egroup
    \else
      \POE@setref{/@@x \POE@key@mirrorwidth\space 0.5 mul def}%
      \ifx\POE@key@mirrortype\POE@str@mirrortype@plain\else
        \POE@setref{\POE@key@mirrordepth\space 0.5 mul dup /@@y0 ED /@@y ED}%
      \fi
    \fi
  \else
    \POE@setref{/@@x \POE@key@mirrorwidth\space 0.5 mul def}%
    \ifx\POE@key@mirrortype\POE@str@mirrortype@plain\else
      \POE@setref{\POE@key@mirrordepth\space 0.5 mul dup /@@y0 ED /@@y ED}%
    \fi
  \fi
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\mirror@nodes}
%    \begin{macrocode}
\def\mirror@nodes{%
  \begin@CompIfc
%    \end{macrocode}
% Add this one reflective interface in any case
%    \begin{macrocode}
  \ifdim\POE@key@mirrorradius pt=0pt
    \addto@pscode{%
      {0 0} {1 0} 
      \POE@key@mirrorwidth\space -0.5 mul dup neg 
      refl {PlainIfc} }%
  \else
    \addto@pscode{%
      {0 0} {0 \POE@key@mirrorradius\space neg} 
      \POE@key@mirrorwidth\space -0.5 mul dup neg 
      refl {CurvedIfc} }%
  \fi
%    \end{macrocode}
% A second interface exists only for semitrans mirrors
%    \begin{macrocode}
  \ifx\POE@key@mirrortype\POE@str@mirrortype@semitrans
%    \end{macrocode}
% if no second mirror radius was specified, use the same curvature of the first interface.
%    \begin{macrocode}
    \ifx\POE@key@mirrorradiusB\@empty 
      \ifdim\POE@key@mirrorradius pt=0pt
        \addto@pscode{%
          {0 \POE@key@mirrordepth} {1 0} 
          @@x neg @@x trans {PlainIfc} }%
      \else
        \addto@pscode{%
          {0 \POE@key@mirrordepth}
          {0 \POE@key@mirrorradius\space neg}
          \POE@key@mirrorwidth\space -0.5 mul dup neg
          trans {CurvedIfc} }%
      \fi
    \else
%    \end{macrocode}
% the second interface is plain if it should not have the curvature of the first interface.
%    \begin{macrocode}
      \addto@pscode{%
        {0 \POE@key@mirrordepth
        dup \POE@key@mirrorradius\space mul 0 lt {
          dup sign \POE@key@mirrorradius\space @@x capHeight mul add
        } if} 
       {1 0} @@x neg @@x trans {PlainIfc} }%
     \fi
%    \end{macrocode}
% Rearrange the two interfaces depending on the sign of mirrordepth
%    \begin{macrocode}
    \addto@pscode{%
      \ifdim\POE@key@mirrordepth pt<-0.0001pt
        12 6 roll 2
      \else
        \ifdim\POE@key@mirrordepth pt< 0.0001pt
          6 {pop} repeat
        \fi
        1
      \fi
      \POE@key@n
    }%
    \end@AmbCompIfc
  \else
    \addto@pscode{1 }%
    \end@CompIfc
  \fi
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\mirror@comp}
%    \begin{macrocode}
\def\mirror@comp{%
  \edef\@ht{%
    \POE@key@mirrorwidth\space\pst@number\psyunit mul 0.5 mul %
  }%
  \edef\@dp{\POE@key@mirrordepth\space\pst@number\psxunit mul }%
  \edef\@r{\POE@key@mirrorradius\space\pst@number\psxunit mul }%
  \edef\@postcode{%
    neg 5 -1 roll exch 5 2 roll 90 add exch 90 add exch ArcR %
  }%
  \edef\@extpostcode{%
    neg \@dp add 5 -1 roll exch 5 2 roll 90 add exch 90 add %
  }%
  \ifdim\POE@key@mirrorradius pt=0pt
%    \end{macrocode}
% plain mirror 
%    \begin{macrocode}
    \edef\@ht{\POE@key@mirrorwidth\space 0.5 mul }%
    \ifx\POE@key@mirrortype\POE@str@mirrortype@piezo
      \psframe[style=PiezoMirror,
               dimen=outer](! \@ht 4 div 0)%
                           (! \@ht -4 div \@ht 2.5 div)
      \ifx\POE@key@extnode\@empty
        \psbezier[fillstyle=none](! 0 \@ht 2.5 div)%
                                 (! 0 \@ht 1.5 div)%
                                 (! \@ht 2 div \@ht 2 div)%
                                 (! \@ht 4 div \@ht)
      \fi
    \else\ifx\POE@key@mirrortype\POE@str@mirrortype@extended
      \psframe[style=ExtendedMirror]%
        (! \@ht neg \POE@key@mirrordepth\space )%
        (! \@ht 0)
    \else\ifx\POE@key@mirrortype\POE@str@mirrortype@semitrans
      \psframe[style=SemitransMirror]%
        (! \@ht neg \POE@key@mirrordepth\space )%
        (! \@ht 0)
    \fi\fi\fi
    \ifx\POE@key@mirrortype\POE@str@mirrortype@semitrans
      \psline[linewidth=\POE@key@mirrorlinewidth]%
        (! \@ht neg 0)(! \@ht 0)
    \else
      \psline[linewidth=\POE@key@mirrorlinewidth]%
        (! \@ht neg \POE@clwh)(! \@ht \POE@clwh)
    \fi
  \else
%    \end{macrocode}
% concave/convex mirror
%    \begin{macrocode}
    \ifdim\POE@key@mirrorradius pt<0pt
      \def\POE@temparc{arc }
    \else
      \def\POE@temparc{arcn }
    \fi
    \ifodd
      \ifx\POE@key@mirrortype\POE@str@mirrortype@extended 1
      \else\ifx\POE@key@mirrortype\POE@str@mirrortype@semitrans 1
      \else 0
      \fi\fi
%    \end{macrocode}
% extended or semitrans mirrortype
%    \begin{macrocode}
      \bgroup
      \ifx\POE@key@mirrortype\POE@str@mirrortype@extended
        \psset{style=ExtendedMirror}
      \else\ifx\POE@key@mirrortype\POE@str@mirrortype@semitrans
        \psset{style=SemitransMirror}
      \fi\fi
        \begin@ClosedObj
          \addto@pscode{%
            \pst@optexpdict \@ht \@r rightCurvedIfc \@postcode
            \ifx\POE@key@mirrorradiusB\@empty
              \@ht \@r rightCurvedIfc \@extpostcode \POE@temparc
            \else
              0 \@dp
%    \end{macrocode}
% For positive mirrorradius and positive mirror depth, add the cap
% height so that mirrordepth is the minimum mirror depth. For both
% negative radius and depth, subtract the cap height.
%    \begin{macrocode}
              \POE@key@mirrordepth\space\POE@key@mirrorradius\space
              mul 0 gt {
                dup sign \@r \@ht capHeight mul add
              } if
              rlineto 2 \@ht mul 0 rlineto
            \fi
            closepath end}%
        \end@ClosedObj
      \egroup
    \fi
%    \end{macrocode}
% draw the reflective interface
%    \begin{macrocode}
    \bgroup
      \psset{linewidth=\POE@key@mirrorlinewidth, fillstyle=none}
      \begin@OpenObj
        \addto@pscode{\POE@dict{ \@ht \@r rightCurvedIfc \@postcode }}%
      \end@OpenObj
    \egroup
  \fi
  \ifPOE@variable
    \psarc[style=VariableStyle]%
      (! \POE@key@mirrorwidth\space 0.5 mul 0.4 sub 
         \ifdim\POE@key@mirrorradius pt=0pt
           0
         \else
           \POE@key@mirrorradius\space dup \POE@dict{sign} neg exch
           \POE@key@mirrorwidth\space  0.5 mul \POE@dict{capHeight} mul
         \fi){0.6}{-20}{20}
    \psarc[style=VariableStyle]%
      (! 0.4 \POE@key@mirrorwidth\space 0.5 mul sub
         \ifdim\POE@key@mirrorradius pt=0pt
           0
         \else
           \POE@key@mirrorradius\space dup \POE@dict{sign} neg exch
           \POE@key@mirrorwidth\space  0.5 mul \POE@dict{capHeight} mul
         \fi){0.6}{160}{200}
   \fi
}%
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{lens}
%
% \begin{macro}{\lens@ref}
%    \begin{macrocode}
\def\lens@ref{%
  \ifdim\POE@key@lensradiusleft pt=0pt
    \edef\@th{0 }%
  \else
    \edef\@th{%
      \ifPOE@thicklens 
        \POE@key@lenswidth\space 0.5 mul
      \else
        \ifdim\POE@key@lensradiusleft pt<0pt
          \POE@key@lensheight\space 0.075 mul
        \else
          \POE@key@lensradiusleft
          \POE@key@lensheight\space 0.5 mul capHeight
        \fi
      \fi
    \space}%     
  \fi
  \ifdim\POE@key@lensradiusright pt=0pt\else
    \edef\@th{%
      \@th\space
      \ifPOE@thicklens 
        \POE@key@lenswidth\space 0.5 mul
      \else
        \ifdim\POE@key@lensradiusright pt<0pt
          \POE@key@lensheight\space 0.075 mul
        \else
          \POE@key@lensradiusright
          \POE@key@lensheight\space 0.5 mul capHeight
        \fi
      \fi
      \space add
    \space}%
  \fi
  \POE@setref{%
    /@@y \POE@key@lensheight\space 0.5 mul def
    /@@x \@th 0.5 mul def
  }%
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\lens@nodes}
%    \begin{macrocode}
\def\lens@nodes{%
  \newOptexpComp{%
    {@@x neg 0} 
    \ifdim\POE@key@lensradiusleft pt=0pt 
      {0 1} 
      \POE@key@lensheight\space -0.5 mul dup neg
      trans {PlainIfc}
    \else 
      {\POE@key@lensradiusleft\space 0} 
      \POE@key@lensheight\space -0.5 mul dup neg
      trans {CurvedIfc}
    \fi
    {@@x 0} 
    \ifdim\POE@key@lensradiusright pt=0pt
      {0 1} 
      \POE@key@lensheight\space -0.5 mul dup neg
      trans {PlainIfc}
    \else
      {\POE@key@lensradiusright\space neg 0} 
      \POE@key@lensheight\space -0.5 mul dup neg
      trans {CurvedIfc} 
    \fi
    \POE@key@n
  }%
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\lens@comp}
%    \begin{macrocode}
\def\lens@comp{%
  \addbefore@par{linejoin=1}%
  \begin@ClosedObj
  \addto@pscode{\pst@optexpdict }%
  \def\@th{0}%
  \def\@wd{\POE@key@lenswidth\space\pst@number\psxunit mul 2 div }%
  \def\@ht{\POE@key@lensheight\space\pst@number\psyunit mul 2 div }%
  \def\@rL{\POE@key@lensradiusleft\space\pst@number\psrunit mul }%
  \def\@rR{\POE@key@lensradiusright\space\pst@number\psrunit mul }%
  \ifdim\POE@key@lensradiusleft pt=0pt\else
    \addto@pscode{ \@ht \@rL leftCurvedIfc }%
  \fi
  \ifdim\POE@key@lensradiusright pt=0pt\else
    \addto@pscode{ \@ht \@rR rightCurvedIfc }%
  \fi
  \def\@@x{@@x \pst@number\psxunit mul }%
%    \end{macrocode}
% Check some special cases:
%
% 1) Left is plain - right concave / convex
%    \begin{macrocode}
  \ifdim\POE@key@lensradiusleft pt=0pt
    \ifdim\POE@key@lensradiusright pt=0pt\else
      \addto@pscode{%
        \@@x sub neg 5 1 roll
        \@@x neg \@ht neg moveto ArcR
        \@@x neg \@ht lineto
      }%
    \fi
  \fi
%    \end{macrocode}
% 2) Right is plain - left concave / convex
%    \begin{macrocode}
  \ifdim\POE@key@lensradiusright pt=0pt
    \ifdim\POE@key@lensradiusleft pt=0pt\else
      \addto@pscode{%
        \@@x sub 5 1 roll
        \@@x \@ht moveto ArcL
        \@@x \@ht neg lineto
      }%
    \fi
  \fi
%    \end{macrocode}
% 3) right and left are both curved
%    \begin{macrocode}
  \ifdim\POE@key@lensradiusright pt=0pt\else
    \ifdim\POE@key@lensradiusleft pt=0pt\else
      \addto@pscode{%
        \@@x dup
        7 1 roll sub neg 5 1 roll
        ArcR sub 5 1 roll ArcL
      }%
    \fi
  \fi
  \addto@pscode{closepath 1 setlinejoin end }%
  \end@ClosedObj
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \subsubsection{pinhole}
%
% \begin{macro}{\pinhole@ref}
%    \begin{macrocode}
\def\pinhole@ref{%
  \POE@setref{/@@y \POE@key@outerheight\space 0.5 mul def}%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\pinhole@nodes}
%    \begin{macrocode}
\def\pinhole@nodes{%
  \newOptexpComp{%
    {-1e-4 0} {0 1} @@y0 @@y sub @@y0 @@y add trans {PlainIfc}
    {0 0} {0 1} \POE@key@innerheight\space -0.5 mul dup neg 
    trans {PlainIfc}  
    {1e-4 0} {0 1} @@y0 @@y sub @@y0 @@y add trans {PlainIfc}
    \POE@key@n }%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\pinhole@comp}
%    \begin{macrocode}
\def\pinhole@comp{%
  \ifdim\POE@key@phwidth pt=0pt
    \psline[linewidth=\POE@key@phlinewidth]%
      (! 0 \POE@key@outerheight\space 2 div)%
      (! 0 \POE@key@innerheight\space 2 div)%
    \psline[linewidth=\POE@key@phlinewidth]%
      (! 0 \POE@key@outerheight\space -2 div)%
      (! 0 \POE@key@innerheight\space -2 div)%
  \else
    \pspolygon*[linestyle=none]%
      (! 0 \POE@key@innerheight\space 2 div)%
      (! 0 \POE@key@outerheight\space 2 div)%
      (! \POE@key@phwidth\space\POE@key@outerheight\space 2 div)%
      (! \POE@key@phwidth\space\POE@key@innerheight\space dup neg
         \POE@key@outerheight\space add 2 div add 2 div)%
    \pspolygon*[linestyle=none]%
      (! 0 \POE@key@innerheight\space -2 div)%
      (! 0 \POE@key@outerheight\space -2 div)%
      (! \POE@key@phwidth\space\POE@key@outerheight\space -2 div)%
      (! \POE@key@phwidth\space\POE@key@innerheight\space dup neg 
         \POE@key@outerheight\space add 2 div add -2 div)%
  \fi
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \subsubsection{beamsplitter}
%
% \begin{macro}{\beamsplitter@ref}
%    \begin{macrocode}
\def\beamsplitter@ref{%
  \POE@setref{/@@x \POE@key@bssize\space 0.5 sqrt mul def }%
}%
% \begin{macro}{\beamsplitter@nodes}
%    \begin{macrocode}
\def\beamsplitter@nodes{%
  \edef\@bs@wd{\POE@key@bssize\space 0.5 mul }%
  \ifx\POE@key@bsstyle\POE@str@bsstyle@cube
    \newOptexpCompAmb{%
      {\@bs@wd 2 sqrt div neg dup} {-1 1} \@bs@wd neg \@bs@wd 
      trans {PlainIfc}
      {\@bs@wd 2 sqrt div dup neg} {1 1} \@bs@wd neg \@bs@wd
      trans {PlainIfc}
      {0 0} {1 0} \@bs@wd 2 sqrt mul dup neg exch 
      trans {PlainIfc}
      {\@bs@wd 2 sqrt div dup} {-1 1} \@bs@wd neg \@bs@wd 
      trans {PlainIfc}
      {\@bs@wd 2 sqrt div neg dup neg} {1 1} \@bs@wd neg \@bs@wd 
      trans {PlainIfc} 
      3 \POE@key@n
    }%
  \else\ifx\POE@key@bsstyle\POE@str@bsstyle@plate
    \newOptexpCompAmb{%
      {0 0} {1 0} \@bs@wd neg \@bs@wd trans {PlainIfc} 1 1 }%
  \fi\fi
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\beamsplitter@comp}
%    \begin{macrocode}
\def\beamsplitter@comp{%
  \edef\@bs@wd{\POE@key@bssize\space 2.0 div }%
  \ifx\POE@key@bsstyle\POE@str@bsstyle@cube
    \psline[arrows=cc-cc](! \@bs@wd neg 2 sqrt mul 0)
                  (! \@bs@wd 2 sqrt mul 0)
    \rput[c]{45}(0,0){%
      \psframe(! \@bs@wd neg \@bs@wd neg)(! \@bs@wd \@bs@wd)
    }
  \else\ifx\POE@key@bsstyle\POE@str@bsstyle@plate
    \psline(! \@bs@wd neg 2 sqrt mul 0)(! \@bs@wd 2 sqrt mul 0)
  \fi\fi
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \subsubsection{crystal}
%
% \begin{macro}{\crystal@ref}
%    \begin{macrocode}
\def\crystal@ref{%
  \let\POE@key@optboxwidth\POE@key@crystalwidth
  \let\POE@key@optboxheight\POE@key@crystalheight
  \optbox@ref
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\crystal@comp}
%    \begin{macrocode}
\def\crystal@comp{%
  \edef\@wd{\POE@key@crystalwidth\space 0.5 mul }
  \edef\@ht{\POE@key@crystalheight\space 0.5 mul }
  \psframe(! \@wd neg \@ht neg)(! \@wd \@ht)
  \ifPOE@voltage%
    \psline(!\@wd 4 div 3 mul neg \@ht)%
           (! \@wd 4 div 3 mul neg \@ht 0.2 add)
    \pscircle[fillstyle=solid, fillcolor=white]%
      (! \@wd 4 div 3 mul neg \@ht 0.2 add){0.04}
    \psline(! \@wd 4 div 3 mul neg \@ht neg)%
           (! \@wd 4 div 3 mul neg \@ht neg 0.2 sub)%
    \psline(! \@wd 4 div 3 mul neg 0.15 sub \@ht neg 0.2 sub)%
           (! \@wd 4 div 3 mul neg 0.15 add \@ht neg 0.2 sub)%
  \fi
  \ifPOE@lamp
    \rput(! \@wd \@ht){%
      \psset{style=CrystalLamp}%
      \rput(0, 0.4){\crystal@lamp}%
    }%
  \fi
  \ifdim\POE@key@caxislength pt=0pt\else
    \def\@cl{%
      \POE@key@caxislength\space 
      \ifPOE@caxisinv -1 mul\space\fi
    }%
    \psline[style=CrystalCaxis](! 0 \@cl \POE@dict{sign} \@ht mul)%
                               (! 0 \@cl \POE@dict{sign} neg \@ht mul \@cl sub)%
  \fi
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\crystal@lamp}
%    \begin{macrocode}
\def\crystal@lamp{%
  \pscurve[fillstyle=none](-0.015, 0)(-0.03, -0.045)(-0.06, -0.075)%
          (-0.075, -0.15)(0, -0.21)(0.075, -0.15)(0.06, -0.075)%
          (0.03, -0.045)(0.015, 0)
  \multido{\i=-30+40}{7}{%
    \rput{\i}(0, -0.135){%
      \psline(-0.105, 0)(-0.18, 0)
    }%
  }%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \subsubsection{polarization}
%
% \begin{macro}{\polarization@comp}
%    \begin{macrocode}
\def\polarization@comp{%
  \edef\@sz{\POE@key@polsize\space 0.5 mul }%
  \psset{style=Polarization}%
  \ifx\POE@key@poltype\POE@str@pol@polparallel
    \psline[arrows=<->](! 0 \@sz neg)(! 0 \@sz)
  \fi
  \ifx\POE@key@poltype\POE@str@pol@polperp
    \psdot(0,0)
    \pscircle[fillstyle=none](0,0){0.12}
  \fi
  \ifx\POE@key@poltype\POE@str@pol@polmisc
    \psline[arrows=<->](! 0 \@sz neg)(! 0 \@sz)
    \psdot(0,0)
    \pscircle[fillstyle=none](0,0){0.12}
  \fi
  \ifx\POE@key@poltype\POE@str@pol@polrcirc
    \psellipticarc[fillstyle=none, arrows=->]%
      (0,0)(! \@sz 2 div \@sz){20}{-20}
  \fi
  \ifx\POE@key@poltype\POE@str@pol@pollcirc
    \psellipticarc[fillstyle=none, arrows=<-]%
      (0,0)(! \@sz 2 div \@sz){20}{-20}
  \fi
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \subsubsection{optgrating}
%
% \begin{macro}{\optgrating@ref}
%    \begin{macrocode}
\def\optgrating@ref{%
  \POE@setref{/@@x \POE@key@gratingwidth\space 0.5 mul def}%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\optgrating@comp}
%    \begin{macrocode}
\def\optgrating@comp{%
  \edef\@cnt{\POE@key@gratingcount\space}%
  \edef\@wd{\POE@key@gratingwidth\space 0.5 mul }%
  \ifdim\POE@key@gratingheight pt<\POE@key@gratingdepth pt
    \edef\@ht{\POE@key@gratingdepth\space}%
  \else
    \edef\@ht{\POE@key@gratingheight\space}%
  \fi
%    \end{macrocode}
% Shift the grating by its depth if gratingalign is set to 'center'.
%    \begin{macrocode}
  \ifx\POE@key@gratingalign\POE@str@top
    \edef\@dp{\POE@key@gratingdepth\space}%
    \edef\@bl{0 }%
  \else
    \edef\@dp{0 }%
    \edef\@bl{\POE@key@gratingdepth\space neg }%
    \edef\@ht{\@ht \POE@key@gratingdepth\space sub }%
  \fi
  \edef\@step{\POE@key@gratingwidth\space\@cnt div }%
  \ifx\POE@key@gratingtype\POE@str@gratingtype@blazed
    \pscustom[linewidth=\POE@key@gratinglinewidth, linejoin=1]{%
      \psline[liftpen=1](! \@wd \@dp)(! \@wd \@ht)%
                        (! \@wd neg \@ht)(! \@wd neg \@dp)%
      \multido{\i=0+1}{\POE@key@gratingcount}{%
        \psline[liftpen=1]%
          (! \@wd neg \i\space \@step mul add \@dp)%
          (! \@wd neg \i\space 
             \ifPOE@reverse\else 1 add \fi \@step mul add \@bl)%
          (! \@wd neg \i\space 1 add \@step mul add \@dp)%
      }%
      \closepath
    }%
  \else\ifx\POE@key@gratingtype\POE@str@gratingtype@binary
    \pscustom[linewidth=\POE@key@gratinglinewidth, linejoin=1]{%
      \psline[liftpen=1](! \@wd \@dp)(! \@wd \@ht)%
                        (! \@wd neg \@ht)(! \@wd neg \@dp)%
      \multido{\i=0+1}{\POE@key@gratingcount}{%
        \psline[liftpen=1]%
          (! \@wd neg \i\space \@step mul add \@dp)%
          (! \@wd neg \i\space \@step mul add \@bl)%
          (! \@wd neg \i\space 0.5 add \@step mul add \@bl)%
          (! \@wd neg \i\space 0.5 add \@step mul add \@dp)%
          (! \@wd neg \i\space 1 add \@step mul add \@dp)%
      }%
      \closepath
    }%
  \fi\fi
  \ifPOE@variable
    \psarc[style=VariableStyle]%
      (! \POE@key@gratingwidth\space 0.5 mul 0.4 sub
         \POE@key@gratingheight\space 0.5 mul){0.6}{-20}{20}
    \psarc[style=VariableStyle]%
      (! 0.4 \POE@key@gratingwidth\space 0.5 mul sub
         \POE@key@gratingheight\space 0.5 mul){0.6}{160}{200}
   \fi
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \subsubsection{optbox}
%
% \begin{macro}{\optbox@ref}
%    \begin{macrocode}
\def\optbox@ref{%
  \POE@setref{%
    /@@x \POE@key@optboxwidth\space 0.5 mul def
    /@@y \POE@key@optboxheight\space 0.5 mul def
  }%
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\optbox@comp}
%    \begin{macrocode}
\def\optbox@comp{%
  \edef\@wd{\POE@key@optboxwidth\space 0.5 mul }
  \edef\@ht{\POE@key@optboxheight\space 0.5 mul }
  \psframe[dimen=outer](! \@wd neg \@ht neg)(! \@wd \@ht)
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \subsubsection{optplate}
%
% \begin{macro}{\optplate@ref}
%    \begin{macrocode}
\def\optplate@ref{%
  \POE@setref{/@@y \POE@key@plateheight\space 0.5 mul def }%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\optplate@comp}
%    \begin{macrocode}
\def\optplate@comp{%
   \psline[linewidth=\POE@key@platelinewidth]%
     (! \POE@dict{0 @@y neg})(! \POE@dict{0 @@y})
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{optdetector}
%
% \begin{macro}{\optdetector@ref}
%    \begin{macrocode}
\def\optdetector@ref{%
  \ifx\POE@key@detsize\@empty
    \POE@setref{%
      /@@y \POE@key@detheight\space 0.5 mul def
      /@@x \POE@key@detwidth\space 0.5 mul def
    }%
  \else
    \POE@setref{%
      /@@y \POE@key@detsize\space 0.5 mul def
      /@@x \POE@key@detsize\space 0.5 mul
      \ifx\POE@key@dettype\POE@str@dettype@round 0.5 mul\fi
      \space def
    }%
  \fi
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\optdetector@nodes}
%    \begin{macrocode}
\def\optdetector@nodes{%
  \dipole@nodes
  \ifx\POE@key@dettype\POE@str@dettype@round
    \pnode(! \POE@dict{@@x0 @@x -0.2 mul add} 0){\oenodeCenter{}}%
  \fi
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\optdetector@comp}
%    \begin{macrocode}
\def\optdetector@comp{%
  \ifx\POE@key@dettype\POE@str@dettype@round
    \psellipticwedge(!\POE@dict{@@x0 @@x sub @@y0})%
      (!\POE@dict{@@x 2 mul @@y}){-90}{90}%
  \else\ifx\POE@key@dettype\POE@str@dettype@diode
    \ifx\POE@key@detsize\@empty
      \ifdim\POE@key@detwidth pt<\POE@key@detheight pt
        \def\@sz{\POE@key@detwidth\space 0.5 mul }%
      \else
        \def\@sz{\POE@key@detheight\space 0.5 mul }%
      \fi
    \else
      \def\@sz{\POE@key@detsize\space 0.5 mul }%
    \fi
    \psframe[dimen=outer](! \POE@dict{@@x neg @@y neg})%
                         (! \POE@dict{@@x @@y})%
    \bgroup
      \psset{style=DetectorStyle}
      \pspolygon(! \@sz -0.2 mul \@sz -0.4 mul)%
                (! \@sz 0.6 mul \@sz -0.4 mul)%
                (! \@sz 0.2 mul \@sz 0.4 mul)%
      \psline(! \@sz -0.2 mul \@sz 0.4 mul \POE@clwh add)%
             (! \@sz 0.6 mul \@sz 0.4 mul \POE@clwh add)
      \psset{arrows=->, arrowinset=0, arrowscale=0.8}%
      \psline(! \@sz -0.8 mul \@sz 0.3 mul)%
             (! \@sz -0.3 mul \@sz 0.15 mul)%
      \psline(! \@sz -0.8 mul 0)(! \@sz -0.3 mul \@sz -0.15 mul)%
    \egroup
  \fi\fi
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \subsubsection{optretplate}
%
% \begin{macro}{\optretplate@ref}
%    \begin{macrocode}
\def\optretplate@ref{%
   \POE@setref{%
     /@@y \POE@key@plateheight\space 0.5 mul def
     /@@x \POE@key@platewidth\space 0.5 mul def
   }%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\optretplate@comp}
%    \begin{macrocode}
\def\optretplate@comp{%
   \edef\@ht{\POE@key@plateheight\space 0.5 mul }%
   \edef\@wd{\POE@key@platewidth\space 0.5 mul }%
   \psframe(! \@wd neg \@ht neg)(! \@wd \@ht)
   \psline{cc-cc}(! \@wd neg \@ht)(! \@wd \@ht neg)
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \subsubsection{optdiode}
%
% \begin{macro}{\optdiode@ref}
%    \begin{macrocode}
\def\optdiode@ref{%
  \POE@setref{%
    \POE@key@optdiodesize\space 0.5 mul dup /@@y ED /@@x ED 
  }%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\optdiode@comp}
%    \begin{macrocode}
\def\optdiode@comp{%
   \edef\@sz{\POE@key@optdiodesize\space}%
   \psframe[dimen=outer](! \@sz -0.5 mul dup)(!\@sz 0.5 mul dup)
   \pspolygon(! \@sz -0.2 mul \@sz -0.2 mul)
             (! \@sz -0.2 mul \@sz 0.2 mul)
             (! \@sz 0.2 mul 0)
   \psline(! \@sz 0.2 mul \POE@clwh add \@sz 0.2 mul)%
          (! \@sz 0.2 mul \POE@clwh add \@sz -0.2 mul)
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \subsubsection{doveprism}
%
% \begin{macro}{doveprism@ref}
%    \begin{macrocode}
\def\doveprism@ref{%
  \POE@setref{/@@x \POE@key@doveprismwidth\space 0.5 mul def
              /@@y \POE@key@doveprismheight\space 0.5 mul def}%
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\doveprism@nodes}
%    \begin{macrocode}
\def\doveprism@nodes{%
  \newOptexpComp{%
    /@htsq @@y 2 sqrt mul def
    {@@x neg @@y add 0} {1 1} 
    @htsq neg @htsq trans {PlainIfc}
    {0 @@y neg} {1 0} 
    @@x neg dup neg
    refl {PlainIfc}
    {@@x @@y sub 0} {-1 1} 
    @htsq neg @htsq trans {PlainIfc} 
    \POE@key@n true 
  }%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\doveprism@comp}
%    \begin{macrocode}
\def\doveprism@comp{%
   \edef\@ht{\POE@key@doveprismheight\space 0.5 mul }%
   \edef\@wd{\POE@key@doveprismwidth\space 0.5 mul }%
   \pspolygon(! \@wd neg \@ht neg)%
             (! \@wd \@ht neg)%
             (! \@wd \@ht 2 mul sub \@ht)%
             (! \@ht 2 mul \@wd sub \@ht)%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{glanthompson}
%
% \begin{macro}{\glanthompson@ref}
%    \begin{macrocode}
\def\glanthompson@ref{%
  \POE@setref{/@@x \POE@key@glanthompsonwidth\space 0.5 mul def
    /@@y \POE@key@glanthompsonheight\space 0.5 mul def
  }%
}%      
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\glanthompson@nodes}
%    \begin{macrocode}
\def\glanthompson@nodes{%
  \newOptexpCompAmb{%
    {@@x neg 0} {0 1} @@x neg @@x trans {PlainIfc}
    {@@x 0} {0 1} @@x neg @@x trans {PlainIfc}
    {\POE@key@glanthompsongap\space -0.5 mul 0} {@@x neg @@y} 0 0 trans {PlainIfc}
    {0 @@y neg} {1 0} @@y neg @@y trans {PlainIfc}
    {0 @@y} {1 0} @@y neg @@y trans {PlainIfc}
    3 \POE@key@n
  }
}%      
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\glanthompson@comp}
%    \begin{macrocode}
\def\glanthompson@comp{%
  \ifdim\POE@key@glanthompsongap pt>0pt
    \pspolygon(!\POE@dict{@@x neg @@y})%
              (!\POE@dict{@@x neg @@y neg})%
              (!\POE@dict{@@x \POE@key@glanthompsongap\space sub @@y neg})
    \pspolygon(!\POE@dict{@@x neg \POE@key@glanthompsongap\space add @@y})%
              (!\POE@dict{@@x @@y})%
              (!\POE@dict{@@x @@y neg})%
  \else
    \psframe(!\POE@dict{@@x neg @@y neg})(!\POE@dict{@@x @@y})
    \psline[arrows=cc-cc](!\POE@dict{@@x neg @@y})(!\POE@dict{@@x @@y neg})
  \fi
}%      
%    \end{macrocode}
% \end{macro}
% \subsubsection{pentaprism}
%
% \begin{macro}{\pentaprism@nodes}
%    \begin{macrocode}
\def\pentaprism@nodes{%
  \edef\@sz{\POE@key@pentaprismsize\space}%
  \newOptexpComp{%
    {\@sz 2 sqrt -2 mul div dup } {-1 1} 
    \@sz -0.5 mul dup neg trans {PlainIfc}
    {\@sz 2 sqrt div 67.5 cos \@sz mul 
      67.5 sin 2 mul div sub \@sz 2 div}
    {67.5 cos \@sz mul 67.5 sin div neg \@sz} 
     \@sz 22.5 cos div -0.5 mul dup neg refl {PlainIfc}
    {\@sz 2 sqrt div neg 67.5 cos \@sz mul 
      67.5 sin 2 mul div add \@sz 2 div}
    {67.5 cos \@sz mul 67.5 sin div \@sz}
     \@sz 22.5 cos div -0.5 mul dup neg refl {PlainIfc}
    {\@sz 2 sqrt 2 mul div dup neg} {1 1} 
    \@sz -0.5 mul dup neg trans {PlainIfc} 
    \POE@key@n
  }%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\pentaprism@comp}
%    \begin{macrocode}
\def\pentaprism@comp{%
  \edef\@sz{\POE@key@pentaprismsize\space}%
  \pscustom{%
    \psline(! \@sz 2 sqrt div 0)%
           (! \@sz 2 sqrt div 67.5 cos \@sz mul 
              67.5 sin div sub \@sz)%
           (! 67.5 cos \@sz mul 67.5 sin div \@sz 
              2 sqrt div sub \@sz)%
           (! \@sz 2 sqrt div neg 0)%
           (! 0 \@sz 2 sqrt div neg)%
    \closepath
  }%
}%
%    \end{macrocode}
% \end{macro}
% 
% \subsubsection{optprism}
%
% \begin{macro}{\optprism@nodes}
%    \begin{macrocode}
\def\optprism@nodes{%
  \edef\@sz{\POE@key@prismsize\space}%
  \edef\@ang{\POE@key@prismangle\space 0.5 mul\space}%
  \edef\@hshift{%
    \ifx\POE@key@prismalign\POE@str@auto
      \POE@dict{OEangle} 1e-5 lt {
        0
      } {
        \@sz 0.6 mul \@ang tan mul \POE@dict{OEangle} 0.5 mul tan div 
      } ifelse
    \else
      0
    \fi
  }%
  \newOptexpComp{%
    {\@sz -0.6 mul \@ang tan mul \@hshift neg} 
    {90 \@ang sub dup cos exch sin} 
    \@sz \@ang cos div dup -0.4 mul exch 0.6 mul trans {PlainIfc}
    {\@sz 0.6 mul \@ang tan mul \@hshift neg} 
    {90 \@ang add dup cos exch sin} 
    \@sz \@ang cos div dup -0.4 mul exch 0.6 mul trans {PlainIfc} 
    \POE@key@n true }%
  \pnode(! 0 \@hshift neg){\oenodeCenter{}}
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\optprism@comp}
%    \begin{macrocode}
\def\optprism@comp{%
  \edef\@sz{\POE@key@prismsize\space}%
  \edef\@altan{\POE@key@prismangle\space 0.5 mul tan }%
  \edef\@hshift{%
    \ifx\POE@key@prismalign\POE@str@auto
      \POE@dict{OEangle} 1e-5 lt {
        0
       } {
        \@sz 0.6 mul \@altan mul \POE@dict{OEangle} 0.5 mul tan div 
       } ifelse
    \else
      0
    \fi
  }%
  \pspolygon(! \@sz neg \@altan mul \@sz -0.4 mul \@hshift sub)
            (! \@sz \@altan mul \@sz -0.4 mul \@hshift sub)
            (! 0 \@sz 0.6 mul \@hshift sub)
}%
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{rightangleprism}
%
% \begin{macro}{\rightangleprism@ref}
%    \begin{macrocode}
\def\rightangleprism@ref{%
  \POE@setref{%
    tx@EcldDict begin
      OEangle 0.5 mul
      { x sin modA mul } 
      { OEangle x sub sin modB mul }
      NewtonSolving pop
    end
    /@htA exch def
    OEangle 0.5 mul exch sub /dOEangle exch def
    /@OEtrafo {dOEangle matrix rotate dtransform } bind def
  }%
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\rightangleprism@nodes}
%    \begin{macrocode}
\def\rightangleprism@nodes{%
  \edef\@sz{\POE@key@raprismsize\space}%
  \edef\@ht{\POE@dict{OEangle 0.5 mul sin modA mul} }%
  \newOptexpComp{%
    {@htA neg @htA \@sz 0.5 mul sub @OEtrafo} {1 0 @OEtrafo} 
    @htA \@sz 0.5 mul sub @htA trans {PlainIfc}
    {@htA neg 0 @OEtrafo} {1 1 @OEtrafo} 
    @htA 2 sqrt mul dup \@sz 2 sqrt div sub exch refl {PlainIfc}
    {@htA 0 @OEtrafo} {-1 1 @OEtrafo} 
    @htA 2 sqrt mul dup \@sz 2 sqrt div sub exch refl {PlainIfc}
    {@htA dup \@sz 0.5 mul sub @OEtrafo} {1 0 @OEtrafo} 
    @htA neg \@sz 0.5 mul @htA sub trans {PlainIfc} 
    \POE@key@n 
  }%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\rightangleprism@comp}
%    \begin{macrocode}
\def\rightangleprism@comp{%
  \edef\@sz{\POE@key@raprismsize\space 0.5 mul }%
  \pspolygon(!\POE@dict{\@sz neg @htA \@sz sub @OEtrafo})
            (!\POE@dict{\@sz @htA \@sz sub @OEtrafo})
            (! 0 \POE@dict{@htA @OEtrafo})%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \subsection{Fiber components}
%
% \subsubsection{optfiber}
%
% \begin{macro}{optfiber@ref}
%    \begin{macrocode}
\def\optfiber@ref{%
  \POE@setref{/@@x \POE@key@fiberloopsep\space\POE@key@fiberloops\space
      1 sub mul 0.5 mul def }%
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\optfiber@nodes}
%    \begin{macrocode}
\def\optfiber@nodes{%
  \newOptexpFiberComp{{@@x neg 0} {@@x 0}}%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\optfiber@comp}
%    \begin{macrocode}
\def\optfiber@comp{%
  \edef\@f@cnt{\POE@key@fiberloops\space}%
  \edef\@f@r{\POE@key@fiberloopradius\space}%
  \edef\@f@sep{\POE@key@fiberloopsep\space}%
  \parametricplot[plotpoints=200, style=Fiber]{0}{1}{%
    t 360 mul \@f@cnt mul sin \@f@r mul \@f@sep 
    \@f@cnt 1 sub mul t 0.5 sub mul add
     1 t 360 mul \@f@cnt mul cos sub \@f@r mul
  }%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \subsubsection{optmzm}
%
% \begin{macro}{\optmzm@ref}
%    \begin{macrocode}
\def\optmzm@ref{%
  \POE@setref{%
    /@@x \POE@key@optmzmwidth\space 0.5 mul def
    /@@y \POE@key@optmzmheight\space 0.5 mul def
  }%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\optmzm@comp}
%    \begin{macrocode}
\def\optmzm@comp{%
  \psframe[dimen=outer](! \POE@dict{@@x neg @@y neg})%
                       (!\POE@dict{@@x @@y})
  \bgroup
    \ifPOE@usefiberstyle
      \psset{style=Fiber, arrows=-, ArrowInside=-}
    \fi
    \psline(! \POE@dict{@@x} neg 0)(! \POE@dict{@@x} -0.7 mul 0)%
           (! \POE@dict{@@x} -0.4 mul \POE@dict{@@y} 0.6 mul)%
           (! \POE@dict{@@x 0.4 mul @@y 0.6 mul})%
           (! \POE@dict{@@x} 0.7 mul 0)(! \POE@dict{@@x} 0)%
           (! \POE@dict{@@x} 0.7 mul 0)%
           (! \POE@dict{@@x 0.4 mul @@y -0.6 mul})%
           (! \POE@dict{@@x -0.4 mul @@y -0.6 mul})%
           (! \POE@dict{@@x} -0.7 mul 0)%
  \egroup
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{optfilter} 
%
% \begin{macro}{\optfilter@ref}
%    \begin{macrocode}
 \def\optfilter@ref{%
  \POE@setref{%
    \POE@key@filtersize\space 0.5 mul dup /@@y ED /@@x ED 
    /@@ang 
    \ifx\POE@key@innercompalign\POE@str@absolute
      /N@\oenodeRefA{} /N@\oenodeRefB{} SlopeAngle \POE@key@angle sub
    \else
      \POE@key@filterangle
    \fi def
  }%
 }%
\let\optfilter@nodes\dipole@nodes
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\optfilter@comp}
%    \begin{macrocode}
\def\optfilter@comp{%
  \edef\@sz{\POE@key@filtersize\space 0.5 mul }%
  \def\filter@curve{%
    \parametricplot[plotstyle=curve,arrows=-]{-1}{1}{%
      t \@sz mul 0.7 mul t Pi mul RadtoDeg 
      90 add cos 0.2 \@sz mul mul}%
  }%
  \psframe[dimen=outer](! \@sz neg dup)(! \@sz dup)
  \psrotate(\oenodeCenter{}){!\POE@dict{@@ang}}{%
  \psset{style=FilterStyle}%
    \ifx\POE@key@filtertype\POE@str@filtertype@bandpass
      \psline(! -0.3 \@sz mul -0.65 \@sz mul)%
             (! 0.3 \@sz mul -0.35 \@sz mul)%
      \psline(! -0.3 \@sz mul 0.35 \@sz mul)%
             (! 0.3 \@sz mul 0.65 \@sz mul)%
      \rput(! 0 -0.5 \@sz mul){\filter@curve}
      \rput(0, 0){%
        \ifPOE@usefiberstyle
          \psset{style=Fiber}
        \fi
        \filter@curve}
      \rput(! 0 0.5 \@sz mul){\filter@curve}
    \else\ifx\POE@key@filtertype\POE@str@filtertype@bandstop
      \psline(! -0.3 \@sz mul -0.15 \@sz mul)%
             (! 0.3 \@sz mul 0.15 \@sz mul)%
      \rput(! 0 -0.5 \@sz mul){%
        \ifPOE@usefiberstyle
          \psset{style=Fiber}
        \fi
        \filter@curve}
        \rput(0, 0){\filter@curve}
        \rput(! 0 0.5 \@sz mul){%
          \ifPOE@usefiberstyle
            \psset{style=Fiber}
          \fi
          \filter@curve}
    \else\ifx\POE@key@filtertype\POE@str@filtertype@lowpass
      \psline(! -0.3 \@sz mul -0.15 \@sz mul)%
             (! 0.3 \@sz mul 0.15 \@sz mul)%
      \psline(! -0.3 \@sz mul 0.35 \@sz mul)%
             (! 0.3 \@sz mul 0.65 \@sz mul)%
      \rput(! 0 -0.5 \@sz mul){%
        \ifPOE@usefiberstyle
          \psset{style=Fiber}
        \fi
        \filter@curve}
        \rput(0, 0){\filter@curve}
        \rput(! 0 0.5 \@sz mul){\filter@curve}
    \else\ifx\POE@key@filtertype\POE@str@filtertype@highpass
      \psline(! -0.3 \@sz mul -0.15 \@sz mul)%
             (! 0.3 \@sz mul 0.15 \@sz mul)%
      \psline(! -0.3 \@sz mul -0.65 \@sz mul)%
             (! 0.3 \@sz mul -0.35 \@sz mul)%
      \rput(! 0 0.5 \@sz mul){%
        \ifPOE@usefiberstyle
          \psset{style=Fiber}
        \fi
        \filter@curve}
        \rput(0, 0){\filter@curve}
        \rput(! 0 -0.5 \@sz mul){\filter@curve}
  \fi\fi\fi\fi
  }%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
%
%\subsubsection{optamp}
%
% \begin{macro}{optamp@ref}
%    \begin{macrocode}
\def\optamp@ref{%
  \POE@setref{/@@x \POE@key@optampwidth\space 0.5 mul def
            /@@y \POE@key@optampheight\space 0.5 mul def
          }%
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\optamp@nodes}
%    \begin{macrocode}
\def\optamp@nodes{%
  \newOptexpFiberComp{{@@x neg 0} {@@x 0}}%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\optamp@comp}
%    \begin{macrocode}
\def\optamp@comp{%
  \def\@wd{\POE@key@optampwidth\space 0.5 mul }%
  \def\@ht{\POE@key@optampheight\space 0.5 mul }%
  \pspolygon(! \@wd 0)(! \@wd neg \@ht)(! \@wd neg \@ht neg)
\ignorespaces}%
%    \end{macrocode}
% \end{macro} 
%
%\subsubsection{polcontrol}
%
% \begin{macro}{polcontrol@ref}
%    \begin{macrocode}
\def\polcontrol@ref{%
  \ifx\POE@key@polcontroltype\POE@str@polcontroltype@linear
    \POE@setref{/@@x \POE@key@polcontrolsize\space 2 mul def}%
  \else
    \POE@setref{/@@x \POE@key@polcontrolsize\space 1.5 mul def}%
  \fi
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\polcontrol@nodes}
%    \begin{macrocode}
\def\polcontrol@nodes{%
  \newOptexpFiberComp{{@@x neg 0} {@@x 0}}%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\polcontrol@comp}
%    \begin{macrocode}
\def\polcontrol@comp{%
  \edef\@sz{\POE@key@polcontrolsize\space}%
  \ifPOE@optexpenv
    \psline[style=Fiber, arrows=-, ArrowInside=-](\oenodeIn{})(\oenodeOut{})
  \fi
  \bgroup
    \ifPOE@usefiberstyle
      \psset{style=Fiber, arrows=-, ArrowInside=-}%
    \fi
    \ifx\POE@key@polcontroltype\POE@str@polcontroltype@linear
      \multips(! -2 \@sz mul \@sz)(! 2 \@sz mul 0){3}{%
        \pscircle(0,0){\POE@key@polcontrolsize}%
      }%
    \else
      \pscircle(! -1.5 \@sz mul \@sz neg){\POE@key@polcontrolsize}
      \pscircle(! 0 \@sz){\POE@key@polcontrolsize}%
      \pscircle(! 1.5 \@sz mul \@sz neg){\POE@key@polcontrolsize}
    \fi
  \egroup
  \ifPOE@optexpenv\else
    \psline[style=Fiber, arrows=-, ArrowInside=-](\oenodeIn{})(\oenodeOut{})
  \fi  
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \subsubsection{optisolator}
%
% \begin{macro}{\optisolator@ref}
%    \begin{macrocode}
\def\optisolator@ref{%
  \POE@setref{%
    /@@x \POE@key@isolatorwidth\space 0.5 mul def
    /@@y \POE@key@isolatorheight\space 0.5 mul def
  }%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\optisolator@comp}
%    \begin{macrocode}
\def\optisolator@comp{%
  \edef\@ht{\POE@key@isolatorheight\space 0.5 mul }%
  \edef\@wd{\POE@key@isolatorwidth\space 0.5 mul }%
  \psframe[dimen=outer](! \@wd neg \@ht neg)(! \@wd \@ht)
  \psline[style=IsolatorArrow,
          arrows=->](! \@wd neg 0.6 mul 0)(!\@wd 0.6 mul 0)
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \subsubsection{optfiberpolarizer}
% \begin{macro}{\optfiberpolarizer@ref}
%    \begin{macrocode}
\def\optfiberpolarizer@ref{%
  \POE@setref{%
    /@@x \POE@key@fiberpolwidth\space 0.5 mul def
    /@@y \POE@key@fiberpolheight\space 0.5 mul def
  }%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\optfiberpolarizer@comp}
%    \begin{macrocode}
\def\optfiberpolarizer@comp{%
  \edef\@ht{\POE@key@fiberpolheight\space 0.5 mul }%
  \edef\@wd{\POE@key@fiberpolwidth\space 0.5 mul }%
  \psframe[dimen=outer](! \@wd neg \@ht neg)(! \@wd \@ht)
  \psline(! \@wd neg 0.2 mul \@ht neg)(!\@wd 0.2 mul \@ht)
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \subsubsection{optswitch}
%
% \begin{macro}{\optswitch@ref}
%    \begin{macrocode}
\def\optswitch@ref{%
  \POE@setref{%
    /@@x \POE@key@switchwidth\space 0.5 mul def
    /@@y \POE@key@switchheight\space 0.5 mul def
  }%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\optswitch@comp}
%    \begin{macrocode}
\def\optswitch@comp{%
  \psframe[dimen=outer](! \POE@dict{@@x neg @@y neg})%
                       (! \POE@dict{@@x @@y})%
%    \end{macrocode}
% storing the linewidth of the object allows for some aesthetic fine tuning 
%    \begin{macrocode}
  \pstVerb{tx@Dict begin /@lw \POE@clw def end}%
  \bgroup
    \ifPOE@usefiberstyle
      \psset{style=Fiber, arrows=-, ArrowInside=-}
    \fi
    \psline[arrows=-](! \POE@dict{@@x} neg 0)%
                     (! \POE@dict{@@x} -0.6 mul @lw sub 0)%
    \psline[arrows=-](! \POE@dict{@@x} 0.6 mul 0)(! \POE@dict{@@x} 0)%
  \egroup
  \ifx\POE@key@switchstyle\POE@str@closed%
    \bgroup
      \ifPOE@usefiberstyle
        \psset{style=Fiber}
      \fi
      \psdot[dotsize=3\pslinewidth](! \POE@dict{@@x} 0.6 mul 0)%
      \psdot[dotsize=3\pslinewidth](! \POE@dict{@@x} -0.6 mul 0)%
      \psline[arrows=-, linewidth=1.5\pslinewidth]%
        (! \POE@dict{@@x} -0.6 mul @lw)(! \POE@dict{@@x} 0.6 mul @lw)%      
    \egroup
  \else
    \psline[arrows=-, linewidth=1.5\pslinewidth]%
      (! \POE@dict{@@x} -0.6 mul @lw add @lw)%
      (! \POE@dict{@@x 0.6 mul @@y 0.6 mul})%
    \pscircle(! \POE@dict{@@x} -0.6 mul 0){\pslinewidth}%
    \psdot[dotsize=3\pslinewidth](! \POE@dict{@@x} 0.6 mul 0)%
  \fi
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{fiberdelayline}
%
% \begin{macro}{\fiberdelayline@ref}
%    \begin{macrocode}
\def\fiberdelayline@ref{%
  \POE@setref{%
    /@@y \POE@key@fdlheight\space 0.5 mul def
    /@@x \POE@key@fdlwidth\space 0.5 mul def
  }%
}%
%    \end{macrocode}
% \end{macro}
%    \begin{macrocode}
\def\POE@get@yarrowscale#1 #2 #3 #4\@nil{%
  \def\POE@tempA{#3\space}%
}%
%    \end{macrocode}
% \begin{macro}{\fiberdelayline@comp}
%    \begin{macrocode}
\def\fiberdelayline@comp{%
  \psframe[dimen=outer](! \POE@dict{@@x neg @@y neg})%
                       (! \POE@dict{@@x @@y})
  \begingroup
    \psset{style=FdlArrow}
    \use@par
    \pst@expandafter\POE@get@yarrowscale{\psk@arrowscale}\@nil
    \def\@arrowshift{%
      \psk@arrowlength\space \psk@arrowsize\space
      \pst@number\pslinewidth\space mul add mul 
      \POE@tempA mul 
      @@y 2.9 mul @@x 0.6 mul atan 2 copy cos mul 3 1 roll sin mul 
      \tx@UserCoor abs exch abs exch\space
    }%
    \psline(! \POE@dict{@@x -0.4 mul @@y -1.6 mul})%
           (! \POE@dict{@@x 0.2 mul @@y 1.3 mul \@arrowshift VecAdd})
  \endgroup
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \subsubsection{fiberbox}
% \begin{macro}{fiberbox@ref}
%    \begin{macrocode}
\def\fiberbox@ref{%
  \POE@setref{%
    /@@x \POE@key@fiberboxwidth\space 0.5 mul def
    @@inht 0 eq @@outht 0 eq and {
      /@@inht \POE@key@fiberboxcountin\space\POE@key@fiberboxsepin\space mul def
      /@@outht \POE@key@fiberboxcountout\space\POE@key@fiberboxsepout\space mul def
    } if
    @@inht \POE@key@fiberboxcountin\space dup 1 add 3 1 roll div mul
    @@outht \POE@key@fiberboxcountout\space dup 1 add 3 1 roll div mul
    max 
    \POE@key@fiberboxheight\space dup @@inht @@outht max gt {
      exch
    } if pop 0.5 mul /@@y exch def
  }%
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fiberbox@nodes}
%    \begin{macrocode}
\def\fiberbox@nodes{%
  \newOptexpFiberComp{%
    0 1 \POE@key@fiberboxcountin\space 1 sub {
      \POE@key@fiberboxcountin\space 1 sub 0.5 mul dup 3 -1 roll sub exch
      0 gt {
        @@inht \POE@key@fiberboxcountin\space 1 sub div mul
      } if
      @@x neg exch ToVec
    } for
    0 1 \POE@key@fiberboxcountout\space 1 sub {
      \POE@key@fiberboxcountout\space 1 sub 0.5 mul dup 3 -1 roll sub exch
      0 gt {
        @@outht \POE@key@fiberboxcountout\space 1 sub div mul
      } if
      @@x exch ToVec
    } for
  }
}%
\def\fiberbox@comp{%
  \psframe[dimen=outer](!\POE@dict{@@x neg @@y neg})(!\POE@dict{@@x @@y})
}%
%    \end{macrocode}
% \end{macro}
%
%
% \subsubsection{optcoupler}
% \begin{macro}{\optcoupler@nodes}
%    \begin{macrocode}
\def\optcoupler@nodes{%
  \edef\@sep{\POE@key@couplersep\space 0.5 mul }%
  \newOptexpFiberComp{%
    {@@x neg @@y0 \@sep add}
    {@@x neg @@y0 \@sep sub}
    {@@x @@y0 \@sep add}
    {@@x @@y0 \@sep sub} }%
  \pnode(0,0){\oenodeCenter{}}
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\POE@coupler@ref}
%    \begin{macrocode}
\def\POE@coupler@ref{%
  \POE@setref{%
    /@@y0
    \ifx\POE@key@coupleralign\POE@str@top
      \POE@key@couplersep\space -0.5 mul
    \else\ifx\POE@key@coupleralign\POE@str@bottom
      \POE@key@couplersep\space 0.5 mul
    \else
      0
    \fi\fi
    def
    /@@x \POE@key@couplerwidth\space 0.5 mul def
    \ifx\POE@key@couplertype\POE@str@couplertype@none
      \POE@key@couplersep
    \else
      \POE@key@couplerheight\space 0.5 mul
    \fi
    \space /@@y ED
  }%
}%
%    \end{macrocode}
% \end{macro}
% 
%    \begin{macrocode}
\let\optcoupler@ref\POE@coupler@ref
%    \end{macrocode}
%
% \begin{macro}{\wdmcoupler@ref}
% The \cs{wdmcoupler} and \cs{wdmsplitter} need a little correction for centered alignment and \opt{couplertype} set to \opt{none}.
%    \begin{macrocode}
\def\wdmcoupler@ref{%
  \POE@coupler@ref
  \ifx\POE@key@couplertype\POE@str@couplertype@none
    \ifx\POE@key@coupleralign\POE@str@center
      \POE@setref{/@@y 0 def }%
    \fi
  \fi
}%
\let\wdmsplitter@ref\wdmcoupler@ref
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\optcoupler@comp}
%    \begin{macrocode}
\def\optcoupler@comp{%
  \ifx\POE@key@couplertype\POE@str@couplertype@none
    \psline[style=Fiber](\oenode{1}{})(\oenode{3}{})
    \psline[style=Fiber](\oenode{2}{})(\oenode{N}{})
  \fi
  \POE@coupler@comp
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\POE@coupler@comp}
%    \begin{macrocode}
\def\POE@coupler@comp{%
  \ifx\POE@key@couplertype\POE@str@couplertype@none
  \else\ifx\POE@key@couplertype\POE@str@couplertype@ellipse
    \psellipse(! 0 \POE@dict{@@y0})(! \POE@dict{@@x @@y})
  \else
    \psframe[dimen=outer](!\POE@dict{@@x neg @@y0 @@y sub})%
                         (!\POE@dict{@@x @@y0 @@y add})%
    \ifx\POE@key@couplertype\POE@str@couplertype@cross
      \psline(! \POE@dict{@@x -0.5 mul @@y0 @@y 0.5 mul sub})%
             (! \POE@dict{@@x 0.5 mul @@y0 @@y 0.5 mul add})%
      \psline(! \POE@dict{@@x -0.5 mul @@y0 @@y 0.5 mul add})%
             (! \POE@dict{@@x 0.5 mul @@y0 @@y 0.5 mul sub})%
    \fi
  \fi\fi
  \ifx\POE@key@couplertype\POE@str@couplertype@cross\else
    \ifPOE@variable
      \begingroup
%    \end{macrocode}
% we set the style this way to be able to access the arrow and line parameters
% already before the psline command
%    \begin{macrocode}
        \psset{style=VariableCoupler}
        \use@par
        \pst@expandafter\POE@get@yarrowscale{\psk@arrowscale}\@nil
        \def\@arrowshift{%
          \psk@arrowlength\space\psk@arrowsize\space
          \pst@number\pslinewidth\space mul add mul 
          \POE@tempA mul 
          1.6 0.8 atan 2 copy cos mul 3 1 roll sin mul
          \tx@UserCoor abs exch abs exch\space
        }%
        \psline(!\POE@dict{@@x -0.4 mul @@y0 @@x sub})%
               (!\POE@dict{@@x 0.4 mul @@x 0.7 mul @@y0 add 
                 \@arrowshift VecAdd})
      \endgroup
    \fi
  \fi
}%
%    \end{macrocode}
% \end{macro}
% 
% \subsubsection{wdmcoupler}
% \begin{macro}{\wdmcoupler@nodes}
%    \begin{macrocode}
\def\wdmcoupler@nodes{%
  \edef\@sep{\POE@key@couplersep\space 0.5 mul }%
  \ifx\POE@key@couplertype\POE@str@couplertype@none
    \ifx\POE@key@coupleralign\POE@str@center
      \edef\@sep{0 }%
    \fi
  \fi
  \newOptexpFiberComp{%
    {@@x neg @@y0 \@sep add}
    {@@x neg  @@y0 \@sep sub}
    {@@x 0}}%
  \pnode(0,0){\oenodeCenter{}}
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\wdmcoupler@comp}
%    \begin{macrocode}
\def\wdmcoupler@comp{%
  \ifx\POE@key@couplertype\POE@str@couplertype@none
    \ifx\POE@key@coupleralign\POE@str@top
      \psline[style=Fiber](\oenode{1}{})(\oenodeOut{})
      \psline[style=Fiber]%
        (!/N@\oenodeOut{} \POE@dict{@GetCenter} 
          \tx@UserCoor \POE@key@couplersep\space sub)(\oenode{2}{})
    \else
      \psline[style=Fiber](\oenode{2}{})(\oenodeOut{})
      \ifx\POE@key@coupleralign\POE@str@bottom
        \psline[style=Fiber]%
          (!/N@\oenodeOut{} \POE@dict{@GetCenter} 
            \tx@UserCoor \POE@key@couplersep\space add)(\oenode{1}{})
      \fi
    \fi
  \fi
  \POE@coupler@comp
}%
%    \end{macrocode}
% \end{macro}
% 
% \subsubsection{wdmsplitter}
% \begin{macro}{\wdmsplitter@nodes}
%    \begin{macrocode}
\def\wdmsplitter@nodes{%
  \edef\@sep{\POE@key@couplersep\space 0.5 mul }%
  \ifx\POE@key@couplertype\POE@str@couplertype@none
    \ifx\POE@key@coupleralign\POE@str@center
      \edef\@sep{0 }%
    \fi
  \fi
  \newOptexpFiberComp{%
    {@@x neg 0}
    {@@x @@y0 \@sep add}
    {@@x @@y0 \@sep sub}}
  \pnode(0,0){\oenodeCenter{}}
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\wdmsplitter@comp}
%    \begin{macrocode}
\def\wdmsplitter@comp{%
  \ifx\POE@key@couplertype\POE@str@couplertype@none
    \ifx\POE@key@coupleralign\POE@str@top
      \psline[style=Fiber](\oenodeIn{})(\oenode{2}{})
      \psline[style=Fiber](! \POE@dict{/N@\oenodeIn{} @GetCenter}
        \tx@UserCoor \POE@key@couplersep\space sub)(\oenode{N}{})
    \else
      \psline[style=Fiber](\oenodeIn{})(\oenode{N}{})
      \ifx\POE@key@coupleralign\POE@str@bottom
        \psline[style=Fiber](! \POE@dict{/N@\oenodeIn{} @GetCenter}
          \tx@UserCoor \POE@key@couplersep\space add)(\oenode{2}{})
      \fi
    \fi
  \fi
  \POE@coupler@comp
}%
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{optcirculator}
%
% \begin{macro}{optcirculator@ref}
%    \begin{macrocode}
\def\optcirculator@ref{%
  \POE@setref{\POE@key@optcircsize\space 0.5 mul dup /@@x ED /@@y ED }%
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\optcirculator@nodes}
%    \begin{macrocode}
\def\optcirculator@nodes{%
  \newOptexpFiberComp{{@@x neg 0} {0 @@y neg} {@@x 0}}%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\optcirculator@comp}
%    \begin{macrocode}
\def\optcirculator@comp{%
  \edef\@sz{\POE@key@optcircsize\space 0.5 mul }%
  \pscircle(0,0){! \@sz}
  \psarc[style=OptCircArrow](0,0)%
    {! \POE@key@optcircsize\space 0.5 mul}%
    {\POE@key@optcircangleA}%
    {\POE@key@optcircangleB}
}%
%    \end{macrocode}
% \end{macro}
% 
% \subsubsection{fibercollimator}
%
% \begin{macro}{fibercollimator@ref}
%    \begin{macrocode}
\def\fibercollimator@ref{%
  \POE@setref{%
    /@@x \POE@key@fibercolwidth\space 0.5 mul def
    /@@y \POE@key@fibercolheight\space 0.5 mul def}%
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\fibercollimator@nodes}
%    \begin{macrocode}
\def\fibercollimator@nodes{%
  \pnode(!\POE@dict{@@x neg} 0){\oenodeIn{}}
  \newOptexpComp{{@@x neg 0} {0 1} @@y neg @@y trans {PlainIfc} 
                 {@@x 0} {0 1} 0 0 trans {PlainIfc} 1 }%
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\fibercollimator@comp}
%    \begin{macrocode}
\def\fibercollimator@comp{%
  \def\@wd{\POE@key@fibercolwidth\space 0.5 mul }%
  \def\@ht{\POE@key@fibercolheight\space 0.5 mul }%
  \pspolygon(!\@wd neg \POE@clwh add \@ht neg)%
            (!\@wd 0)(!\@wd neg \POE@clwh add \@ht)
}%
%    \end{macrocode}
% \end{macro}
%
%</stylefile> 
%
% \chapter{The Postscript header file}
% \makeatletter
%^^A Copied this definition from doc.sty and changed it not to add a
%^^A backslash to the Postscript procedure name in the index.
% \def\SpecialIndex@#1#2{%
%    \@SpecialIndexHelper@#1\@nil
%    \def\@tempb{ }%
%    \ifcat \@tempb\@gtempa
%       \special@index{\quotechar\space\actualchar
%                      \string\verb\quotechar*\verbatimchar
%                      \quotechar\space\verbatimchar#2}%
%    \else
%      \def\@tempb##1##2\relax{\ifx\relax##2\relax
%           \def\@tempc{\special@index{\quotechar##1\actualchar
%                       \string\verb\quotechar*\verbatimchar
%                       \quotechar##1\verbatimchar#2}}%
%         \else
%           \def\@tempc{\special@index{##1##2\actualchar
%                        \string\verb\quotechar*\verbatimchar##1##2\verbatimchar#2}}%
%         \fi}%
%      \expandafter\@tempb\@gtempa\relax
%      \@tempc
%    \fi}
% \makeatother
%
%<*prolog>
%
% This is the dictionary where all components are stored in.
%    \begin{macrocode}
/tx@OptexpDict 200 dict def
tx@OptexpDict begin
/DebugOE false def
/DebugDepth 0 def
/DebugBegin { 
  DebugOE {
    /DebugProcName ED
    DebugDepth 2 mul string
    0 1 DebugDepth 2 mul 1 sub {
      dup 2 mod 0 eq { (|) }{( )} ifelse
      3 -1 roll dup 4 2 roll
      putinterval
    } for
    DebugProcName strcat ==
    /DebugDepth DebugDepth 1 add def
  }{
    pop
  } ifelse
} bind def
/DebugEnd {
  DebugOE {
    /DebugDepth DebugDepth 1 sub def
    DebugDepth 2 mul 2 add string
    0 1 DebugDepth 2 mul 1 sub {
      dup 2 mod 0 eq { (|) }{ ( ) } ifelse
      3 -1 roll dup 4 2 roll
      putinterval
    } for
    dup DebugDepth 2 mul (+-) putinterval
    ( done) strcat ==
  } if
} bind def
/DebugMsg { 
  DebugOE {
    DebugDepth 1 add 2 mul string
    0 1 DebugDepth 2 mul 1 add {
      dup 2 mod 0 eq { (|) }{( )} ifelse
      3 -1 roll dup 4 2 roll
      putinterval
    } for
    exch strcat ==
  }{
    pop
  } ifelse
} bind def
%    \end{macrocode}
% \begin{macro}{strcat}
% Concatenate two strings and leave the result on the stack
% \begin{pssyntax}
%   \PSstring{str1} \PSstring{str2} \PSop{strcat} \PSstring{str1str2}
% \end{pssyntax}
%    \begin{macrocode}
/strcat {
    exch 2 copy
    length exch length add
    string dup dup 5 2 roll
    copy length exch
    putinterval
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{nametostr}
%   Convert a literal name to string. This is required, because some PSTricks
%   parameter like \opt{angleA} do not allow round braces in the argument, so
%   some string must be passed as name and then converted to a string.
% \begin{pssyntax}
%   \PSname{name} \PSop{nametostr} \PSstring{name}
% \end{pssyntax}
%    \begin{macrocode}
/nametostr {
    dup length string cvs
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{PrintWarning}
%   Print a warning about the raytracing. This is enabled or disabled via option
%   \opt{pswarning}.
%    \begin{macrocode}
/PrintWarning {
  (Warning pst-optexp: ) exch strcat ==
} bind def
/CompUnknownWarning {
  (Component ') exch strcat (' unknown) strcat PrintWarning
} bind def
/OneFiberCompWarning {
  (Found only one fiber component in beam path, drawing no beam) PrintWarning
} bind def
/FiberCompWarning {
  (Found a fiber component in beam path, stopping beam path) PrintWarning
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{inttostr}
%    Convert an integer to a string.
% \begin{pssyntax}
%   \PSvar{int} \PSop{inttostr} \PSstring{int}
% \end{pssyntax}
%    \begin{macrocode}
/inttostr {
  dup type /integertype eq {
    dup log 1 add floor cvi string cvs
  } if
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{IfcCopy}
%   Copy an interface \PSvar{from} to an interface \PSvar{to}, must be called
%   within the respective component dictionary. This involves also copying the
%   node associated with the interface.
%   \begin{pssyntax}
%     \PSvar{from} \PSvar{to} \PSop{CopyIfc}
%   \end{pssyntax}
%    \begin{macrocode}
/IfcCopy { 
  2 copy IfcName exch IfcName load dup
  length dict copy def
  name exch NodeName name 3 -1 roll NodeName 
  tx@NodeDict begin
    load dup length dict copy def
  end
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{calcNodes}
%   Calculate the reference node coordinates for reflective components and
%   stores them as \PSvar{X@A}, \PSvar{Y@A}, \PSvar{X@B} and \PSvar{Y@B}. Some
%   other values (\PSvar{modA}, \PSvar{modB}, and \PSvar{OEangle}) are also
%   stored for some special components
% \begin{pssyntax}
%   \PSvar{XB} \PSvar{YB} \PSvar{XA} \PSvar{YA} \PSvar{XG} \PSvar{YG} \PSop{calcNodes}
% \end{pssyntax}
%    \begin{macrocode}
/calcNodes {
  (calcNode) DebugBegin
  /YG exch def /XG exch def
  /ay YG 3 -1 roll sub def
  /ax XG 3 -1 roll sub def
  /by exch YG sub def
  /bx exch XG sub def
  /a ax ay Pyth def
%    \end{macrocode}
% Used by \cs{rightangleprism}.
%    \begin{macrocode}
  /modA a def
  /b bx by Pyth def
  /modB b def
  /cx ax a div bx b div add def
  /cy ay a div by b div add def
  /c@tmp cx cy Pyth def
  /c ax bx add ay by add Pyth def
%    \end{macrocode}
% Used by \cs{rightangleprism} and \cs{optprism}.
%    \begin{macrocode}
  /OEangle c dup mul a dup mul sub b dup mul sub 
             -2 a b mul mul div Acos def
%    \end{macrocode}
% If $c=0$, then set the coordinates of the vector manually depending whether
% \PSvar{a} and \PSvar{b} are parallel or antiparallel.
%    \begin{macrocode}
  c 0 eq {
    ax ay bx by DotProd 0 gt {
%    \end{macrocode}
% $\text{dotprod} > 0$, i.e. \PSvar{a} and \PSvar{b} are parallel.
%    \begin{macrocode}
      /cx ax def
      /cy ay def
    }{
      /cx ay def
      /cy ax neg def
    } ifelse
    /c@tmp a def
  } if
  /X@A XG cx c@tmp div add def
  /Y@A YG cy c@tmp div add def
  /X@B XG cx c@tmp div sub def
  /Y@B YG cy c@tmp div sub def
%    \end{macrocode}
% Test the chirality (the order) of the input points. Input angles $> 90$\textdegree
% don't make sense, in this case we exhange the calculated reference nodes.
%    \begin{macrocode}
  ax by mul ay bx mul sub 0 le {
    Y@A X@A 
    /X@A X@B def
    /Y@A Y@B def
    /X@B exch def
    /Y@B exch def
    modA modB /modA exch def /modB exch def
  } if
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{capHeight}
% Calculate the height \PSvar{a} of a pole cap, used for curved interfaces.
% \begin{pssyntax}
%   \PSvar{R} \PSvar{h} \PSop{capHeight} \PSvar{a}
% \end{pssyntax}
% \PSvar{R} is the circle radius and \PSvar{h} the width of the pole cap.
%    \begin{macrocode}
/capHeight {
    dup mul neg exch abs dup 3 1 roll dup mul add sqrt sub
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{leftCurvedIfc}
%   Calculate some parameters for the «left» interface of a lens. Defines and
%   \PSname{ArcL} which is used later in the code to actually draw the interface
%   curve.
% \begin{pssyntax}
%   \PSvar{h R1} \PSop{leftCurvedIfc} \PSvar{y |R1| alpha\textunderscore b
%     alpha\textunderscore t R1}
% \end{pssyntax}
%    \begin{macrocode}
/leftCurvedIfc {
  /R1 exch def /h exch def
  0 R1 abs dup R1 h capHeight exch sub R1 sign mul dup
  h exch atan exch
  h neg exch atan
  R1 0 lt {
    /ArcL /arcn load def
  } {
    /ArcL /arc load def
  } ifelse
  R1
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{rightCurvedIfc}
%   Analogous to \PSname{leftCurvedIfc} for «right» interfaces, defines
%   \PSname{ArcR} for later use.
% \begin{pssyntax}
%   \PSvar{h R2} \PSop{rightCurvedIfc} \PSvar{y |R2| alpha\textunderscore b
%     alpha\textunderscore t R2}
% \end{pssyntax}
%    \begin{macrocode}
/rightCurvedIfc {
  /R2 exch def /h exch def
  0 R2 abs dup R2 h capHeight sub R2 sign mul dup
  h neg exch atan exch
  h exch atan
  R2 0 lt {
    /ArcR /arcn load def
  } {
    /ArcR /arc load def
  } ifelse
  R2
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{SlopeAngle}
%   Calculate slope angle of a line from \PSname{nodeA} to \PSname{nodeB}.
%   \begin{pssyntax}
%     \PSname{nodeB} \PSname{nodeA} \PSop{SlopeAngle} \PSvar{angle}
%   \end{pssyntax}
%    \begin{macrocode}
/SlopeAngle {
  (SlopeAngle) DebugBegin
  @GetCenter 3 -1 roll @GetCenter @ABVect exch atan
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{DefineExtNode}
%   Constructs the coordinates of an external node based on values that have
%   been set beforehand. \PSvar{xref} and \PSvar{yref} are the values which are
%   defined by \opt{extnode} parameter. \PSvar{RefFac} is defined by parameter
%   \opt{extnodealign}, which determines it the reference of the external node
%   position should be the global coordinate system, or the line between the
%   reference nodes.
% \begin{pssyntax}
%   \PSvar{xref yref} \PSop{DefineExtNode} \PSvar{X Y}  
% \end{pssyntax}
%    \begin{macrocode}
/DefineExtNode {%
  (DefineExtNode) DebugBegin
  @@y mul RefFac mul @@y0 add 
  exch @@x mul RefFac mul @@x0 add exch
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{GetInternalNodeNames}
%   Push all internal node names of \PSstring{basicname} on the
%   stack. If \PSvar{reverse} is \PSvar{true}, the names are pushed in
%   reverse order.
%   \begin{pssyntax}
%     \PSstring{basicname} \PSvar{reverse} \PSop{GetInternalNodeNames}
%     \PSname{N@basicnameN} \ldots{} \PSname{N@basicname1} (if
%     \PSvar{reverse = false})
%   \end{pssyntax}
%    \begin{macrocode}
/GetInternalNodeNames {
  (GetInternalNodeNames) DebugBegin
  /reverse ED
  dup cvn load /N get dup
  reverse { -1 1 } { 1 1 3 -1 roll } ifelse
  { 2 copy eq { pop (N) } { inttostr } ifelse
    3 -1 roll dup 4 1 roll exch NodeName 3 1 roll
  } for
  pop pop
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{GetInternalBeamNodes}
%   This is like \PSvar{GetInternalNodeNames}, but leaves the node
%   coordinates on the stack
% \begin{pssyntax}
%   \PSstring{basicnodename} \PSvar{reverse} \PSop{GetInternalBeamNodes}
%   \PSvar{XN YN \ldots\ X1 Y1} (if \PSvar{reverse = false})
% \end{pssyntax}
%    \begin{macrocode}
/GetInternalBeamNodes {
  (GetInternalBeamNodes) DebugBegin
  [ 3 1 roll GetInternalNodeNames ]
  { @GetCenter } forall
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{GetInternalBeamNodesCompat}
%   Equivalent to \PSvar{GetInternalBeamNodes} only that it checks if the
%   component is ambiguous (i.e. it is a beamsplitter), in which case it returns
%   only the center node. Used only for the deprecated \opt{conn} parameter.
%    \begin{macrocode}
/GetInternalBeamNodesCompat {
  exch dup 3 1 roll (C) NodeName dup tx@NodeDict exch known {
    @GetCenter ToVec 
    3 1 roll pop pop
  } {
    pop GetInternalBeamNodes
  } ifelse
} bind def
/GetInternalBeamNodeCompat {
  exch dup 3 1 roll (C) NodeName dup tx@NodeDict exch known {
    @GetCenter ToVec
    3 1 roll pop pop
  } {
    pop NodeName @GetCenter ToVec
  } ifelse
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{InitOptexpComp}
%   Initialize some global variables for positioning of external
%   nodes. This is called at the beginning of every component.
%    \begin{macrocode}
/InitOptexpComp {%
  /@@x 0 def
  /@@y 0 def
  /@@x0 0 def
  /@@y0 0 def
  /@xref 0 def
  /@yref 0 def
  /RefFac 1 def
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{NewTempNodeComp}
%   If \cs{draw*beam} is invoked with a node as parameter, a
%   temporary \cs{optplane} is defined. The plane vector of this temporary plane
%   is set such that it is perpendicular to the connection between the node and the following
%   interface node. 
%
%   This is the only procedure which sets the \PSname{adjustRel} flag
%   which indicates adjustment of the plane vector rotation depending on
%   the incoming or outgoing connection direction.
% 
%   For an explanation of all other dictionary members, please see
%   \PSvar{NewOptexpComp}.
%   \begin{pssyntax}
%     \PSproc{x y} \PSproc{dx dy} \PSstring{name} \PSproc{scaling}
%     \PSop{NewTempNodeComp}
%   \end{pssyntax}
%    \begin{macrocode}
/NewTempNodeComp {
  (NewTempNodeComp) DebugBegin
  /sc ED
  dup cvn
  6 dict dup 3 1 roll def begin
    /ambiguous false def
    /allowbeaminside false def
    /forcebeaminside false def
    /name ED
    /correct false def
%    \end{macrocode}
% This definition does not work like for \PSvar{NewOptexpComp}, because
% a current point may not be available. Therefore, we translate to the
% $(X, Y)$ node and define $X = Y = 0$.
%    \begin{macrocode}
    {0 0} exch 3 -1 roll exec
    gsave
      translate
      /CompMtrx CM def
    grestore
    /N 1 def
    /n bgRefIndex def
    5 dict dup dup /P@1 ED /P@N ED
    begin
      /mode trans def
      {} 0 0 PlainIfc
    end
  /adjustRel true def
  end
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{CurvedIfc}
% Defines a curved interface.
% \begin{pssyntax}
%   \PSproc{X Y} \PSproc{DX DY} \PSproc{scl} \PSvar{NAlow NAup} \PSop{CurvedIfc}
% \end{pssyntax}
%    \begin{macrocode}
/CurvedIfc {
  5 2 roll
  2 copy 5 3 roll exec 3 -1 roll exec VecAdd 
  5 -1 roll exec /Y ED /X ED
  exch exec 3 -1 roll 3 copy exec /RY ED /RX ED
  3 1 roll NormalizeVec 3 -1 roll exec
  tx@Dict begin Pyth end dup
  3 1 roll mul 1.00001 mul /NAup ED
  mul 1.00001 mul /NAlow ED
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{PlainIfc}
%   \begin{pssyntax}
%     \PSproc{X Y} \PSproc{DX DY} \PSproc{scl} \PSvar{NAlow NAup} \PSop{PlainIfc}
%   \end{pssyntax}
%    \begin{macrocode}
/PlainIfc {
  5 2 roll
  dup 3 -1 roll exec NormalizeVec 3 -1 roll exec 2 copy /DY ED /DX ED
  tx@Dict begin Pyth end dup 4 2 roll
  exch exec 3 -1 roll exec /Y ED /X ED
  3 1 roll mul 1.00001 mul /NAup ED
  mul 1.00001 mul /NAlow ED
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{NewCompIfc}
% Defines a new interface of a component, must be called within \PSvar{NewOptexpComp}.
% \begin{pssyntax}
%   \PSproc{x y} \PSproc{dx dy|rx ry} \PSvar{NAlow NAup mode} 
%   \PSstring{CompName} \PSstring{Name} \PSproc{New\ldots Ifc} \PSproc{scaling} 
%   \PSop{NewCompIfc}
% \end{pssyntax}
% \begin{psarglist}
% \psargitem{\PSproc{x y}} The coordinates of the interface node which lies on the optical axis.??
% \psargitem{\PSproc{dx dy | rx ry}} For a plane interface, this is the vector that describes the plane, for a curved interface this is the
% \psargitem{\PSvar{NAlow NAup}}
% \psargitem{\PSvar{mode}} An integer which characterizes if an interface is
%   reflective or transmittive. You should use the predefined variable
%   \PSname{refl} and \PSname{trans} for this.
% \psargitem{\PSstring{CompName}} The name of the component we are in.
% \psargitem{\PSstring{Name}} The name of the new interface. It is prefixed by «P@».
% \psargitem{\PSproc{\ldots Ifc}} Contain the actual procedure to define the
%   concrete interface type, can be \PSproc{PlainIfc} or
%   \PSproc{CurvedIfc}.
% \end{psarglist}
%    \begin{macrocode}
/NewCompIfc {
  /scl ED
  /next ED
  dup (P@) exch strcat cvn
  6 dict dup
  3 1 roll def
  begin
    3 -1 roll
    /mode ED
    6 -1 roll dup 7 -1 roll
    {scl} 8 -2 roll next
  end
%    \end{macrocode}
% store a new node \PSname{N@NameX}, with X=1..N this node always
% represents the intersection of an untilted and unshifted incoming beam
% on the optical axis with the respective interface
%    \begin{macrocode}
  exec scl ToVec 3 1 roll NodeName @NewNode
} bind def
%    \end{macrocode}
% \end{macro}
% 
% Define some constants.
%    \begin{macrocode}
/relative 0 def /absolute 1 def /center 2 def
/refl 0 def /trans 1 def /absorb 2 def
/desc 0 def /asc 1 def /amb 2 def
/ok 0 def /tir 1 def /missed 2 def
/bgRefIndex 0 def
%    \end{macrocode}
% 
% \begin{macro}{NewOptexpComp}
% \PSvar{NewOptexpComp} creates a new dictionary that contains everything needed
% for an optical component. It contains the following variables:
% \begin{psarglist} 
%   \psargitem{\PSvar{n}} The basic refractive index which was set for the
%   component. This may be overwritten with the \opt{n} option of the
%   \nxLcs{drawbeam} macros.
%
%   \psargitem{\PSvar{CompMtrx}} The transformation matrix at time of
%   the component definition. The method is the same as for the
%   \nxLPack{pst-node} nodes.
%
%   \psargitem{\PSvar{name}} The name of the component. This is build of
%   several components which are put together in the \TeX\ code.
%
%   \psargitem{\PSvar{N}} The number of interfaces of the component.
%
%   \psargitem{\PSvar{P@1\ldots P@N}} The actual
%   interfaces. \PSvar{P@1} and \PSvar{P@N} are always defined, even if
%   \PSvar{N = 1}. In that case the two names link to the same
%   dictionary, so that changes in one of them are automatically present
%   also in the second one.
%
%   \psargitem{\PSproc{sc}} The scaling procedure for the coordinates to convert
%   from \TeX{} to Postscript scaling. In should always be defined as
%   \PSproc{\textbackslash psxunit, \textbackslash psyunit}.
%
%   \psargitem{\PSvar{ambiguous}} There is a class of components (at the
%   moment only \nxLcs{beamsplitter}), which have a central interface
%   \PSvar{P@C} which can be either transmittive or reflective,
%   depending on the previous and following component positions. The
%   mode of the \PSvar{P@C} is determined at the time of the beam
%   drawing and requires special attention.
%
%   \psargitem{\PSvar{correct}} If \opt{true}, the input vectors after
%   the transmittive interfaces are corrected when using
%   \opt{connectifc}.
% \end{psarglist}
%
% \begin{pssyntax}
%   \PSvar{[} \PSproc{x y} \PSproc{dx dy | rx ry} \PSvar{NAlow NAup} 
%   \PSvar{type} \PSproc{\ldots Ifc} 
%   \PSvar{\ldots{} [n] correct? amb? allowbeaminside? forcebeaminside?} 
%   \PSstring{CompName} \PSproc{scaling} \PSop{NewOptexpComp}
% \end{pssyntax}
%    \begin{macrocode}
/NewOptexpComp {
  (NewOptexpComp) DebugBegin
  /sc ED dup cvn
  gsave
  12 dict dup 3 1 roll def begin
  /name ED
  /forcebeaminside ED
  /allowbeaminside ED
  /ambiguous ED
  dup type /booleantype eq not { false } if /correct ED
  tx@Dict begin
    STV {CP T} stopped pop
  end
  /CompMtrx CM def
  grestore
  counttomark dup 6 idiv dup /N ED 6 mul eq { 1 } if 
  cvx 1 EvalRefIndex /n ED
%    \end{macrocode}
% This defines for ambiguous components, which interface coincides with the
% ambiguous interface. 0 indicates that there is no ambiguous interface.
%    \begin{macrocode}
  ambiguous { 
    /ambIfc ED 
  }{ 
    /ambIfc 0 def 
  } ifelse
  1 N eq {
%    \end{macrocode}
% only a single plane is specified, create the aliases.
%    \begin{macrocode}
      name (1) 3 -1 roll {sc} NewCompIfc 
      (1) (N) IfcCopy
  }{
    N -1 1 { %
      dup N eq { pop (N) }{inttostr} ifelse
      exch name 3 1 roll {sc} NewCompIfc
    } for
  } ifelse
  ambiguous ambIfc 0 gt and { 
    ambIfc N eq { (N) }{ ambIfc inttostr } ifelse (C) IfcCopy
  } if
  end
  pop
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{NewOptexpFiberComp}
% \begin{pssyntax}
%   \PSvar{[} \PSvar{x y} \ldots
%   \PSstring{CompName} \PSproc{scaling} \PSop{NewOptexpFiberComp}
% \end{pssyntax}
%    \begin{macrocode}
/NewOptexpFiberComp {
  (NewOptexpFiberComp) DebugBegin
  /sc ED dup cvn
  gsave
  12 dict dup 3 1 roll def begin
  /name ED
  tx@Dict begin
    STV {CP T} stopped pop
  end
  /CompMtrx CM def
  grestore
  counttomark /N ED
  1 N eq {
%    \end{macrocode}
% only a single plane is specified, create the aliases.
%    \begin{macrocode}
    {0 1} 0 0 trans name (1) {PlainIfc} {sc} NewCompIfc 
    (1) (N) IfcCopy
  }{
    N -1 1 {
      dup N eq { pop (N) }{inttostr} ifelse
      {0 1} 0 0 absorb name 6 -1 roll {PlainIfc} {sc} NewCompIfc
    } for
  } ifelse
  end
  pop
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{IfcAlias}
%   Create an alias of an interface. This involves creating also an
%   alias for the associated node.  Must be called withing
%   \PSvar{NewOptexpComp}.
%
% \PSstring{OrigPN} \PSstring{AliasPN} \PSop{IfcAlias}
%    \begin{macrocode}
/IfcAlias {
  2 copy IfcName exch IfcName load def
  tx@NodeDict begin 
    name exch NodeName name 3 -1 roll NodeName load def
  end
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{GetPlaneVec}
%   Push the coordinates of the plane vector on the stack, for curved interfaces
%   this is the tangent at the interface node.
%   \begin{pssyntax}
%     \PSvar{IfcNum} \PSstring{CompName} \PSop{GetPlaneVec} \PSvar{dX dY}
%   \end{pssyntax}
%    \begin{macrocode}
/GetPlaneVec {
  (GetPlaneVec) DebugBegin
  cvn load begin
    IfcName load begin
      currentdict /RX known {
        RX RY CompMtrx dtransform CM idtransform
        neg exch
      } {
        DX DY CompMtrx dtransform CM idtransform
      } ifelse
    end
  end
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{GetIfcCenter}
% Get the center node of a interface, either by specifying the name of the component and the interface number
%   \begin{pssyntax}
%     \PSvar{IfcNum} \PSstring{CompName} \PSop{GetIfcCenter} \PSvar{X Y}
%   \end{pssyntax}
% or by passing an interface procedure generated by \PSvar{PushAllPlanesOnStack}.
%   \begin{pssyntax}
%     \PSproc{Ifc} \PSop{GetIfcCenter} \PSvar{X Y}
%   \end{pssyntax}
%    \begin{macrocode}
/GetIfcCenter {
  (GetIfcCenter) DebugBegin
  dup type /stringtype eq not {
    dup xcheck not {
%    \end{macrocode}
% ambiguous
%    \begin{macrocode}
      0 get (C) exch
    } {
      exec pop pop pop
    } ifelse
  } if
  cvn load begin
    IfcName load begin
      currentdict /RX known {
        X RX sub Y RY sub
      } {
        X Y
      } ifelse
      CompMtrx transform CM itransform
    end
  end
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
% \begin{macro}{GetIfcCenter}
% Get the center node of a interface, either by specifying the name of the component and the interface number
%   \begin{pssyntax}
%     \PSvar{IfcNum} \PSstring{CompName} \PSop{GetIfcCenter} \PSvar{X Y}
%   \end{pssyntax}
% or by passing an interface procedure generated by \PSvar{PushAllPlanesOnStack}.
%   \begin{pssyntax}
%     \PSproc{Ifc} \PSop{GetIfcCenter} \PSvar{X Y}
%   \end{pssyntax}
%    \begin{macrocode}
/GetIfcCenter {
  (GetIfcCenter) DebugBegin
  dup type /stringtype eq not {
    dup xcheck not {
%    \end{macrocode}
% ambiguous
%    \begin{macrocode}
      0 get (C) exch
    } {
      exec pop pop pop
    } ifelse
  } if
  cvn load begin
    IfcName load begin
      currentdict /RX known {
        X RX sub Y RY sub
      } {
        X Y
      } ifelse
      CompMtrx transform CM itransform
    end
  end
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{GetIfcCenterCorr}
% Get the center node of a interface, either by specifying the name of the component and the interface number
%   \begin{pssyntax}
%     \PSvar{IfcNum} \PSstring{CompName} \PSop{GetIfcCenterCorr} \PSvar{X|XCorr Y|YCorr}
%   \end{pssyntax}
%    \begin{macrocode}
/GetIfcCenterCorr {
  (GetIfcCenterCorr) DebugBegin
  cvn load begin
    IfcName load begin
      currentdict /XCorr known {
        XCorr YCorr
      }{
        X Y
      } ifelse
      currentdict /RX known {
        RX neg RY neg VecAdd
      } if
      CompMtrx transform CM itransform
    end
  end
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{TransformInVec}
%   Transform the input vector as specified with \opt{beamangle} and
%   \opt{beamdiv} from coordinates relative to the connection between first and
%   second components to absolute coordinates.
%   \begin{pssyntax}
%     \PSproc{Ifc2} \PSproc{Ifc1} \PSproc{InVec} \PSop{TransformInVec} \PSproc{InVec'}
%   \end{pssyntax}
%    \begin{macrocode}
/TransformInVec {
  (TransformInVec) DebugBegin
  3 1 roll
  GetIfcCenter 4 2 roll
  GetIfcCenter 5 -2 roll
  @ABVect
  3 -1 roll exec 2 copy 6 2 roll
  0 eq exch 0 eq and not {
%    \end{macrocode}
% invec != (0,0)
%    \begin{macrocode}
    exch atan matrix rotate dtransform
  } {
    4 2 roll pop pop
  } ifelse
  ToVec
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{TransformStartPos}
% Startpos is relative to the connection between first and second components
% transform to absolute coordinates and shift by first plane center
% Plane2 Plane1 \PSproc{StartPos} -> \PSproc{StartPos'+Plane1Center}
%    \begin{macrocode}
/TransformStartPos {
  (TransformStartPos) DebugBegin
  exec 2 copy 6 2 roll 0 eq exch 0 eq and not
  3 1 roll GetIfcCenter 4 2 roll
  GetIfcCenter 5 2 roll {
    2 copy 8 2 roll
    @ABVect exch atan matrix rotate dtransform
    VecAdd
  } {
    6 2 roll pop pop pop pop
  } ifelse
  ToVec
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{GetNearestPlane}
%   \begin{pssyntax}
%     \PSvar{X Y} \PSstring{CompName} \PSop{GetNearestPlane} \PSvar{PlaneNumber}
%   \end{pssyntax}
%    \begin{macrocode}
/GetNearestPlane {
  (GetNearestPlane) DebugBegin
  3 copy 1 exch GetIfcCenter @ABDist /dist ED /nearestPlane 1 def
  dup cvn load /N get 2 1 3 -1 roll {
%    \end{macrocode}
% iterate through plane 2 to plane N of CompName 
%    \begin{macrocode}
    4 copy exch GetIfcCenter @ABDist dup dist lt {
      /dist ED /nearestPlane ED
    } {
      pop pop
    } ifelse
  } for
  pop pop pop nearestPlane
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{PushAmbCompPlanesOnStack}
% Components which do not have an unambiguous behaviour (beamslitter, can
% transmit and reflect) like lenses (transmission only) or mirrors (reflection
% only), must be evaluated to see which mode should be used.  Argument is
% [(name) draw], draw is a boolean which is true if the inner beams should be
% drawn.
%    \begin{macrocode}
/PushAmbCompPlanesOnStack {
 (PushAmbCompPlanesOnStack) DebugBegin 
  currentdict /outToPlane undef
  PN IfcCnt eq not {
%    \end{macrocode}
% not the last component, there should be another one on the stack
%    \begin{macrocode}
    exch dup 3 1 roll % nextifc ambcomp nextifc
    dup xcheck not {
%    \end{macrocode}
% the next component is also ambiguos, use its center point as reference.
%    \begin{macrocode}
      0 get (C) exch
    } {
%    \end{macrocode}
% otherwise use the interface on the stack
%    \begin{macrocode}
      exec pop pop pop
    } ifelse
    [ 3 1 roll ] cvx /outToPlane ED
%    \end{macrocode}
% outToPlane is \PSproc{(PN) (compName)}
%    \begin{macrocode}
  } if
%    \end{macrocode}
% the old plane number, without counting the additional planes of the current ambcomp
%    \begin{macrocode}
  /IfcCntTmp IfcCnt def
%    \end{macrocode}
% Load some parameters from \opt{ambcomp}
%    \begin{macrocode}
  aload pop /draw ED /name ED
  name cvn load /N get dup /N ED
%    \end{macrocode}
% If the ambiguous component has only one interface, there exists no internal beam
%    \begin{macrocode}
  1 eq { /draw true def } if
%    \end{macrocode}
% \PSvar{CurrTmp} is the current point of the beam on the interface
% prior to the ambiguos component, \PSvar{CurrVecTmp} its outgoing
% vector. For wide beams, the lower ray is used. These vectors will be
% changed inside this procedure.
%    \begin{macrocode}
  currentdict /Curr known {
    /CurrTmp /Curr load def
    /CurrVecTmp /CurrVec load def
  } {
    /CurrTmp /CurrLow load def
    /CurrVecTmp /CurrVecLow load def
  } ifelse
  PN 1 eq {
%    \end{macrocode}
% If it is the first interface, the starting point is always the (C)
% plane, the mode is set arbitrarily to transmittive.
%    \begin{macrocode}
    [ (C) name name GetRefIndex trans draw] cvx
%    \end{macrocode}
% Now check which is the outgoing plane
%    \begin{macrocode}
    name /outToPlane load GetNextPlane
    dup 0 eq not {
%    \end{macrocode}
% If there is one, i.e. if \PSvar{GetNextPlane} leaves something not
% equal to \PSvar{0} on the stack, this is the plane.
%    \begin{macrocode}
      [ exch name bgRefIndex trans draw ] cvx exch
      /IfcCntTmp IfcCntTmp 1 add def
    } {
      pop
    } ifelse
  }{
%    \end{macrocode}
% It is not the first component, check which interface of the component
% is the nearest one to the current beam point and save its name in
% \PSvar{firstPlane}.
%    \begin{macrocode}
    CurrTmp name GetNearestPlane dup /firstPlane ED
    name isAmbiguousIfc not {
%    \end{macrocode}
% The first interface is not the ambiguous one, put it on the stack and
% calculated the new beam vector.
%    \begin{macrocode}
      firstPlane name
      name firstPlane GetIfcMode
      connectifc { bgRefIndex }{ name GetRefIndex } ifelse
      CurrTmp CurrVecTmp
      10 dict begin HandleInterface end pop 
      ToVec /CurrVecTmp ED ToVec /CurrTmp ED
      [ firstPlane name
      connectifc {
        bgRefIndex
      }{
        name GetRefIndex
      } ifelse
      name firstPlane GetIfcMode
%    \end{macrocode}
% always draw to first interface
%    \begin{macrocode}
      true ] cvx
      /IfcCntTmp IfcCntTmp 1 add def
    } if
    PN IfcCnt eq {
%    \end{macrocode}
% Its the last comp, just put the ambiguous interface on the stack, the mode is irrelevant.
%    \begin{macrocode}
      [ (C) name
      name GetRefIndex
      trans draw ] cvx
      IfcCntTmp IfcCnt gt { exch } if
    }{
%    \end{macrocode}
% Otherwise put the ambiguous interface on the stack and check its mode.
%    \begin{macrocode}
      [ (C) name
      name GetRefIndex
      CurrVecTmp (C) name GetPlaneVec NormalVec outToPlane 
      GetIfcCenter (C) name GetIfcCenter @ABVect DotProd
      0 lt { trans } { refl } ifelse
      dup 6 1 roll
%    \end{macrocode}
% if the ambiguous interface is the first, always draw to it
%    \begin{macrocode}
      IfcCntTmp IfcCnt eq { true }{ draw } ifelse
      ] cvx
      (C) name 4 -1 roll
      connectifc { bgRefIndex }{ name GetRefIndex } ifelse
      CurrTmp CurrVecTmp
      10 dict begin HandleInterface end pop 
      ToVec /CurrVecTmp ED ToVec /CurrTmp ED
%    \end{macrocode}
% now check which is the outgoing plane
%    \begin{macrocode}
      name /outToPlane load GetNextPlane
      dup dup name isAmbiguousIfc exch 0 eq or not {
        [ exch name bgRefIndex trans draw ] cvx exch
        firstPlane name isAmbiguousIfc not { 3 -1 roll } if
        /IfcCntTmp IfcCntTmp 1 add def
      } {
        pop
%    \end{macrocode}
% The ambiguous interface is the last one, correct it to have the bgRefIndex.
%    \begin{macrocode}
        exec 3 -1 roll pop bgRefIndex 3 1 roll [ 6 1 roll ] cvx
        firstPlane name isAmbiguousIfc not { exch } if
      } ifelse
    } ifelse
  } ifelse
  /IfcCnt IfcCntTmp def
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{GetNextPlane}
% \PSstring{comp} \PSproc{outToPlane} \PSop{GetNextPlane} \PSvar{PlaneNumber}
%    \begin{macrocode}
/GetNextPlane {
  (GetNextPlane) DebugBegin
  2 copy (C) 3 -1 roll
  GetIfcCenter 3 -1 roll
  exec GetIfcCenter
  4 2 roll 4 copy @ABVect ToVec /Vec ED
  @ABDist /centerDist ED
  /sprod 1 def
  /nextPlane 0 def
  exch dup 3 1 roll
  cvn load dup /ambIfc get /ambIfc ED /N get 1 1 3 -1 roll {
%    \end{macrocode}
% iterate through all interfaces of CompName which do not coincide with the ambiguous interface
%    \begin{macrocode}
   dup ambIfc eq not {
      3 copy 3 -1 roll 2 copy
      GetPlaneVec Vec 4 2 roll NormalVec 
      Vec DotProd dup sprod lt 5 2 roll
      GetIfcCenter 3 -1 roll exec GetIfcCenter @ABDist 
      centerDist lt and
      { /sprod ED /nextPlane ED } { pop pop } ifelse
    } {
      pop
    } ifelse
  } for
  pop pop nextPlane
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{TraceBeam}
% [ CompN ... Comp1 \PSproc{options} \PSproc{start point} \PSvar{beamangle}
% -> Yn Xn drawToN? ... Y1 X1 drawTo1? Y0 X0
%    \begin{macrocode}
/TraceBeam {
  (Tracebeam) DebugBegin
  AngToVec /InVec ED /StartPoint ED
  /oldbeaminsidelast currentdict /beaminsidelast known { 
    beaminsidelast 
  } { 
    false 
  } ifelse def
%    \end{macrocode}
% execute options
%    \begin{macrocode}
  exec
  connectifc {
    /nbeam bgRefIndex def
  } if
  /startinside startinside beaminsidefirst or def
  /stopinside stopinside beaminsidelast or def
  /PrevCorrect false def
  PrearrangePlanes
  PushAllPlanesOnStack
  currentdict /lastVecTmp known {
    lastVecTmp beamangle matrix rotate dtransform ToVec
  } {
    counttomark 2 ge beamalign relative eq and {
      2 copy /InVec load TransformInVec
    } {
      /InVec load
    } ifelse
  } ifelse
  /CurrVec ED
  currentdict /lastBeamPointTmp known {
    /lastBeamPointTmp load /Curr ED
  }{
    counttomark 2 ge {
      2 copy /StartPoint load  TransformStartPos 
    } {
      /StartPoint load 
    } ifelse
    /Curr ED
  } ifelse
  counttomark /IfcCnt ED 
%    \end{macrocode}
% Init the refractive index
%    \begin{macrocode}
  /n1 bgRefIndex def
  /PN 1 def
  (start looping) DebugMsg
  {
    PN IfcCnt gt {
      exit
    } if
    (checked) DebugMsg
%    \end{macrocode}
% iterate over all planes
%    \begin{macrocode}
    dup xcheck not {
%    \end{macrocode}
% array, not executable
%    \begin{macrocode}
      PushAmbCompPlanesOnStack
    } if
    exec
    /draw ED /Mode ED /n2 ED 2 copy /CompName ED /IfcNum ED
    GetIfcCenter ToVec /CurrCenter ED
    Curr CurrVec 
    connectifc PrevCorrect PN 2 gt and PN 2 eq or and {
      CurrVec CurrCenter PrevCenter PrevMode 
      currentdict /relAngle known 
      { relAngle } { 0 } ifelse connectInterfaces
      /relAngle ED
    } if
    IfcNum CompName Mode n2 8 4 roll HandleInterface
    missed eq {
      counttomark PN 1 sub 3 mul sub {pop} repeat
      (The beam missed an interface) Warning exit
      exit
    } if
    PN 1 eq {
      pop pop
      /draw beaminsidefirst oldbeaminsidelast xor def
    } {
      ToVec /CurrVec ED
    } ifelse
    2 copy
    ToVec /Curr ED 
    draw PN beampathskip 1 add gt and
    counttomark 3 roll
    /PrevCenter /CurrCenter load def
    /lastBeamPointTmp /Curr load def
    currentdict /lastVecTmp known {
      /prevVecTmp /lastVecTmp load def
      /lastVecTmp /CurrVec load def
    } {
      /CurrVec load dup /lastVecTmp ED /prevVecTmp ED
    } ifelse
    /PrevMode Mode def
    CompName cvn load /correct get /PrevCorrect ED
    PN IfcCnt eq {
      exit
    } {
      CurrVec 0 eq exch 0 eq and {
        IfcCnt PN sub {pop} repeat
        (Total internal reflection occured, this is not supported)
        Warning
        exit
      } if
      /PN PN 1 add def
    } ifelse
  } loop
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
% 
% 
% \begin{macro}{sign}
%    \begin{macrocode}
/sign {
    0 ge { 1 } { -1 } ifelse
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{Chirality}
%    \begin{macrocode}
/Chirality {
  4 -1 roll mul 3 1 roll mul sub sign
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{TraceAndFillWideBeam}
% Fill a wide beam. This has an own procedure, because each segment
% of the beam must be filled separately.
% \begin{pssyntax}
%   \PSvar{[} \PSstring{CompN} \PSvar{\ldots{}} \PSstring{Comp1}
%   \PSproc{options} \PSproc{start point up} \PSvar{beamangle\_up}
%   \PSproc{start point low} \PSvar{beamangle\_low} \PSop{FillWideBeam}
% \end{pssyntax}
%    \begin{macrocode}
/TraceAndFillWideBeam {
  (TraceAndFillWideBeam) DebugBegin
  AngToVec /InvecLow ED /StartLow ED 
  AngToVec /InvecUp ED /StartUp ED 
%    \end{macrocode}
% execute user options
%    \begin{macrocode}
  exec
  connectifc {
    /nbeam bgRefIndex def
  } if
  /startinside startinside beaminsidefirst or def
  /stopinside stopinside beaminsidelast or def
%    \end{macrocode}
% Number of segments already drawn
%    \begin{macrocode}
  /DrawnSegm 0 def
%    \end{macrocode}
% whether the previous plane required correction of the input vector (used only with \opt{connectifc})
%    \begin{macrocode}
  /PrevCorrect false def
  PrearrangePlanes
  PushAllPlanesOnStack
  currentdict /lastVecTmpUp known 
  currentdict /lastVecTmpLow known and {
    /CurrVecLow lastVecTmpLow beamangle matrix rotate dtransform ToVec def
    /CurrVecUp lastVecTmpUp beamangle matrix rotate dtransform ToVec def
  }{
%    \end{macrocode}
% If the \opt{beamangle} is not absolute, use the connection between the first
% two planes as reference and transform the input vectors accordingly.
%    \begin{macrocode}
    beamalign relative eq counttomark 2 ge and {
      2 copy /InvecLow load TransformInVec /CurrVecLow ED
      2 copy /InvecUp load TransformInVec /CurrVecUp ED
    } {
      /CurrVecLow /InvecLow load def
      /CurrVecUp /InvecUp load def
    } ifelse
  } ifelse
%    \end{macrocode}
% If \opt{loadbeampoints} is set, the nodes \PSname{lastBeamPointTmpLow} and
% \PSname{lastBeamPointTmpUp} are defined and used as starting points.
%    \begin{macrocode}
  currentdict /lastBeamPointTmpLow known 
  currentdict /lastBeamPointTmpUp known and {
    /lastBeamPointTmpLow load /CurrLow ED
    /lastBeamPointTmpUp load /CurrUp ED
%    \end{macrocode}
% The lower and upper beam vectors must possibly swapped if the
% intersection points are loaded from a previous beam, but the beam
% divergence is specified manually for this beam only. We must make
% sure, that negative divergence gives a contracting beam.
%    \begin{macrocode}
    loadbeam not beamdiv 0 eq not and {
      CurrVecLow CurrVecUp Chirality 
      CurrLow CurrUp @ABVect CurrVecLow CurrVecUp VecAdd Chirality 0 lt { neg } if
      beamdiv sign eq not {
        /CurrVecLow load /CurrVecUp load /CurrVecLow ED /CurrVecUp ED
      } if
    } if
  } {
%    \end{macrocode}
% Transform the beam vectors relative to the connection between the first two interfaces.
%    \begin{macrocode}
    counttomark 2 ge {
      2 copy /StartLow load TransformStartPos /CurrLow ED
      2 copy /StartUp load TransformStartPos /CurrUp ED
    } {
      /StartLow load /CurrLow ED
      /StartUp load /CurrUp ED
    } ifelse
  } ifelse
  /PrevVecUp /CurrVecUp load def
  /PrevVecLow /CurrVecLow load def
%    \end{macrocode}
% \PSvar{IfcCnt} is the number of interfaces pushed on the stack by
% \PSvar{PushAllPlanesOnStack}. This number may be corrected later if an
% ambiguous components is among them.
%    \begin{macrocode}
  counttomark /IfcCnt ED 
  /n1 bgRefIndex def
  /CurrR false def
  /ret missed def
  /PN 1 def
  {
    PN IfcCnt gt {
      exit
    } if
    dup xcheck not {
%    \end{macrocode}
% Found an array (not executable) instead of a procedure. This is an ambiguous
% component, resolve the interfaces depending on the input vector and
% surrounding interfaces. This can change \PSvar{IfcCnt}.
%    \begin{macrocode}
      PushAmbCompPlanesOnStack
    } if
%    \end{macrocode}
% push the interface on the stack
%    \begin{macrocode}
    exec
%    \end{macrocode}
% \PSvar{draw} indicates if the beam to the current interface should be drawn.
%    \begin{macrocode}
    PN beampathskip 1 add gt and /draw ED
%    \end{macrocode}
% \PSvar{Mode} stores the mode (transmittive or reflective) of the current interface.
%    \begin{macrocode}
    /Mode ED /n2 ED 2 copy /CompName ED /IfcNum ED
%    \end{macrocode}
% \PSvar{CurrPCenter} holds the coordinates of the current interface center.
%    \begin{macrocode}
    GetIfcCenter ToVec /CurrPCenter ED
    /oldn1 n1 def
%    \end{macrocode}
% Calculate new upper vector and intersection point
%    \begin{macrocode}
    CurrUp CurrVecUp
    connectifc PrevCorrect PN 2 gt and PN 2 eq or and {
      CurrVecUp CurrPCenter PrevPCenter PrevMode 
      currentdict /relAngleUp known { relAngleUp } { 0 } ifelse 
      connectInterfaces /relAngleUp ED
    } if
    /CurrUp load /PrevUp ED
    IfcNum CompName Mode n2 8 4 roll HandleInterface
    dup /ret ED
    missed eq {
      counttomark {pop} repeat 
      (The upper beam missed an interface) Warning exit
    } if
    ToVec /CurrVecUp ED
    ToVec /CurrUp ED
    /n1 oldn1 def
%    \end{macrocode}
% Calculate new lower vector and intersection point
%    \begin{macrocode}
    /CurrLow load /PrevLow ED
    CurrLow CurrVecLow
    connectifc PrevCorrect PN 2 gt and PN 2 eq or and  {
      CurrVecLow CurrPCenter PrevPCenter PrevMode 
      currentdict /relAngleLow known { relAngleLow } { 0 } ifelse 
      connectInterfaces /relAngleLow ED
    } if
    IfcNum CompName Mode n2 8 4 roll HandleInterface
    dup missed eq {
      /ret ED
      (The lower beam missed an interface) Warning
      counttomark {pop} repeat exit
    } if
    tir eq ret tir eq or {
      /ret tir def
    } {
      /ret ok def
    } ifelse
    ToVec /CurrVecLow ED
    ToVec /CurrLow ED
%    \end{macrocode}
% lower done
%    \begin{macrocode}
    /PrevR CurrR def
    PrevR type /realtype eq {
      /CurrCenter load /PrevCenter ED
    } if
    IfcNum CompName isCurved {
      IfcNum CompName LoadIfc
      tx@Dict begin Pyth end /CurrR ED
      ToVec /CurrCenter ED
    } {
      /CurrR false def
      /CurrCenter false def
    } ifelse
    PN 1 gt currentdict /fillBeam known and {
      draw {
        /DrawnSegm DrawnSegm 1 add def
        PrevUp moveto CurrUp lineto
        IfcNum CompName isCurved {
          CurrCenter CurrUp CurrLow 
          4 copy 3 -1 roll eq 3 1 roll eq and {
            6 {pop} repeat
          } {
            TangentCrosspoint
            CurrLow CurrR arct
          } ifelse
        } {
          CurrLow lineto
        } ifelse
        PrevLow lineto
        PrevR type /booleantype eq not {
%    \end{macrocode}
% previous interface was also curved
%    \begin{macrocode}
          PrevCenter PrevLow PrevUp
          4 copy 3 -1 roll eq 3 1 roll eq and {
            6 {pop} repeat
          } {
            TangentCrosspoint
            PrevUp PrevR arct
          } ifelse
        } {
          PrevUp lineto
        } ifelse
      } if
      Mode refl eq draw and
      draw not DrawnSegm 0 gt and or {
        fillBeam newpath
        /DrawnSegm 0 def
      } if
    } if
    PN 1 eq {
%    \end{macrocode}
% At the first interface, we only determine the actual intersection
% points with the interfaces, the beam vectors are not changed and must
% be reset to the previous values.
%    \begin{macrocode}
      /CurrVecUp /PrevVecUp load def
      /CurrVecLow /PrevVecLow load def
    } if
%    \end{macrocode}
% If the beam should also be stroked, push the coordinates and the 'draw' information on the stack
%    \begin{macrocode}
    strokeBeam {
      CurrUp draw CurrLow draw counttomark 1 add 6 roll
    } if
    PN IfcCnt eq ret tir eq or {
      DrawnSegm 0 gt currentdict /fillBeam known and { 
        fillBeam newpath 
        /DrawnSegm 0 def
      } if
      ret tir eq {
        IfcCnt PN sub {pop} repeat
        (Total internal reflection occured, this is not supported) 
        Warning
      } if
      exit
    } if
    /PN PN 1 add def
    /PrevVecUp /CurrVecUp load def
    /PrevVecLow /CurrVecLow load def
    /PrevPCenter /CurrPCenter load def
    /PrevMode Mode def
    CompName cvn load /correct get /PrevCorrect ED
  } loop
  DrawnSegm 0 gt currentdict /fillBeam known and {
    fillBeam newpath
    /DrawnSegm 0 def
  } if
  ret missed eq not {
    currentdict /lastVecTmpUp known currentdict /lastVecTmpLow known and dup {
      /lastVecTmpUp load /lastVecTmpLow load 3 -1 roll
    } if
%    \end{macrocode}
% Check if Up and Low must be swapped for next beam. This depends both
% on the relative orientation (chirality) of the incoming beam vector
% and the vector between the two intersection points CurrUp and CurrLow,
% and the direction of the beam vector.
%
% The intersection points are swapped if the angle of the beam vector is
% between $90°+\epsilon$ and $-90°+\epsilon$ and the chirality is
% positive, or if the beam vector points to the right, positive
% half-circle and the chirality is negative. The $\epsilon$ is
% introduced to get the correct order for $\pm 90°$ despite numerical
% errors.
%    \begin{macrocode}
    CurrLow CurrUp @ABVect % from Low to Up
    PrevVecUp PrevVecLow VecAdd
    2 copy 6 2 roll
    Chirality 0 lt
    3 1 roll 2 copy pop -1e-5 lt
    3 1 roll exch 1e-5 lt exch 0 lt and or xor {
%    \end{macrocode}
% swap upper and lower beam points for next beam
%    \begin{macrocode}
      /lastBeamPointTmpUp /CurrLow load def
      /lastBeamPointTmpLow /CurrUp load def
      /lastVecTmpUp /CurrVecLow load def
      /lastVecTmpLow /CurrVecUp load def
    } {
      /lastBeamPointTmpLow /CurrLow load def
      /lastBeamPointTmpUp /CurrUp load def
      /lastVecTmpUp /CurrVecUp load def
      /lastVecTmpLow /CurrVecLow load def
    } ifelse
    not {
      /lastVecTmpUp load /lastVecTmpLow load
    } if
    /prevVecLow ED /prevVecUp ED
  } if
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{isAmbiguous}
%   Check if \PSvar{compname} is ambiguous, i.e. if it can have alternating beam
%   paths depending on the input and output plane (e.g. beamsplitter can either
%   transmit or reflect a beam).
%   \begin{pssyntax}
%     \PSstring{compname} \PSop{isAmbiguous} \PSvar{boolean}
%   \end{pssyntax}
%    \begin{macrocode}
/isAmbiguous { 
  cvn load dup /ambiguous known {
    /ambiguous get
  } { 
    pop false
  } ifelse
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{isAmbiguousIfc}
%   Check if interface \PSvar{IfcNum} is the ambiguous interface of \PSvar{compname}.
%   \begin{pssyntax}
%     \PSvar{IfcNum} \PSstring{compname} \PSop{isAmbiguousIfc} \PSvar{boolean}
%   \end{pssyntax}
%    \begin{macrocode}
/isAmbiguousIfc { 
  cvn load dup /ambiguous known {
    /ambIfc get eq
  } { 
    pop pop false
  } ifelse
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{isCurved}
%  Check if interface \PSvar{IfcNum} of componente \PSvar{compname} is curved.
%   \begin{pssyntax}
%     \PSvar{IfcNum} \PSstring{compname} \PSop{isCurved} \PSvar{bool}
%   \end{pssyntax}
%    \begin{macrocode}
/isCurved {
  cvn load begin
    IfcName load /RX known
  end
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{HandleInterface}
% \begin{pssyntax}
% \PSvar{IfcNum} \PSstring{CompName} \PSvar{mode n2 X0 Y0 Xin Yin} 
% \PSop{HandleInterface} 
% \PSvar{X0' Y0' Xout Yout status}
% \end{pssyntax}
%    \begin{macrocode}
/HandleInterface {
  (HandleInterface) DebugBegin
  /Yin ED /Xin ED /Y0 ED /X0 ED /n2 ED /mode ED
  2 copy 2 copy LoadIfc
  6 -2 roll isCurved { CurvedInterface }{ PlainInterface } ifelse
%    \end{macrocode}
% IfcNum CompName X0' Y0' Xout Yout status
%
% Check if X0' Y0' are within the numerical aperture of the interface
%    \begin{macrocode}
  dup missed eq not useNA connectifc not and and {
    7 3 roll 2 copy 9 2 roll
    4 2 roll 2 copy
    %% X0' Y0' Xout Yout status X0' Y0' IfcNum CompName IfcNum CompName
    cvn load begin IfcName load dup /NAlow get exch /NAup get end
    2 copy lt {
      4 2 roll 2 copy LoadIfc NormalizeVec
      6 -2 roll isCurved {
        neg exch
      } if
      %% ... X0' Y0' NAlow NAup X Y dXp dYp
      8 -2 roll 6 -2 roll
      %% ... NAlow NAup dXp dYp X0' Y0' X Y
      @ABVect DotProd
      dup 4 -1 roll ge 3 1 roll ge and not 
      {
        pop missed
      } if
    }{
      6 {pop} repeat
    } ifelse
  } {
    7 -2 roll pop pop
  } ifelse
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{LoadIfc}
% \begin{pssyntax}
% \PSvar{IfcNum} \PSstring{CompName} \PSop{LoadIfc} \PSvar{X Y} \PSvar{dX|RY dY|RY}
% \end{pssyntax}
%    \begin{macrocode}
/LoadIfc {
  (LoadIfc) DebugBegin
  cvn load begin
    IfcName load begin
      X Y
      CompMtrx transform CM itransform
      currentdict /RX known { RX RY }{ DX DY } ifelse
      CompMtrx dtransform CM idtransform
    end
  end
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{isFreeray}
%   Check if \PSvar{compname} is a free-ray componente by checking if there is a
%   refractive index associated with it.
%   \begin{pssyntax}
%     \PSstring{compname} \PSop{isFreeray} \PSvar{boolean}
%   \end{pssyntax}
%    \begin{macrocode}
/isFreeray { 
  cvn load /n known 
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{/compIsKnown}
% Check if a component is known.
%    \begin{macrocode}
/compIsKnown {
  dup type /stringtype eq { cvn } if
  tx@OptexpDict exch known
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{PrearrangePlanes}
%   \begin{pssyntax}
%     \PSvar{[} \PSstring{CompN} \PSvar{\ldots} \PSvar{Comp1} \PSop{PrearrangePlanes}\\
%     \PSvar{[} \PSvar{desc|asc} \PSstring{CompN} \PSvar{\ldots} \PSvar{desc|asc} \PSstring{Comp1}
%   \end{pssyntax}
%    \begin{macrocode}
/PrearrangePlanes {
  (PrearrangePlanes) DebugBegin
  counttomark dup 2 lt {
    dup 0 eq { 
      (Found no component on stack, drawing no beam) PrintWarning
    }{
%    \end{macrocode}
% Only one component, draw always in ascending order. We must still
% check in /PushAllPlanesOnStack if the component has only one
% interface.
%    \begin{macrocode}
      exch dup
      compIsKnown {
        dup isFreeray {
          asc exch 3 -1 roll
        }{
          OneFiberCompWarning
          pop
        } ifelse
      }{
        CompUnknownWarning
      } ifelse
    } ifelse
    /N 0 def
  }{
%    \end{macrocode}
% We have a minimum of two components on stack
%    \begin{macrocode}
    /N ED
    /CompA ED dup /CompB ED
%    \end{macrocode}
% Check, if the components have been defined
%    \begin{macrocode}
    CompA compIsKnown CompB compIsKnown and {
      CompA isFreeray {
        CompA isAmbiguous {
          amb dup CompA
        } {
          CompB isAmbiguous {
            1 CompA GetIfcCenter (C) CompB GetIfcCenter @ABDist
            (N) CompA GetIfcCenter (C) CompB GetIfcCenter @ABDist
          } {
            1 CompA GetIfcCenter 
            1 CompB GetIfcCenter 
            (N) CompB GetIfcCenter 
            true OrderNodes exch pop
            (N) CompA GetIfcCenter 
            1 CompB GetIfcCenter 
            (N) CompB GetIfcCenter 
            true OrderNodes exch pop
          } ifelse
          le { desc } { asc } ifelse dup CompA
        } ifelse
        counttomark 2 roll
      }{
        FiberCompWarning
        counttomark 1 sub { pop } repeat
        /N 0 def
      } ifelse
    }{
%    \end{macrocode}
% One of the first two components was not defined, do not draw any beam
%    \begin{macrocode}
      /N 0 def
      CompA compIsKnown not {CompA}{CompB} ifelse
      CompUnknownWarning
    } ifelse
  } ifelse
  2 1 N {
    /i ED exch /CompB ED
    CompB compIsKnown not {
      counttomark i 1 sub 2 mul 1 add sub { pop } repeat
      CompB CompUnknownWarning
      exit
    } if
    CompB isFreeray not {
      counttomark i 1 sub 2 mul 1 add sub { pop } repeat
      FiberCompWarning
      exit
    } if
    CompB isAmbiguous not {
      dup desc eq { 1 } { dup amb eq { (C) }{ (N) } ifelse } ifelse 
      CompA GetIfcCenter
      1 CompB GetIfcCenter
      (N) CompB GetIfcCenter false OrderNodes dup dup
%    \end{macrocode}
% check if we have a NodeIfc
%    \begin{macrocode}
      4 -1 roll CompA exch 5 -1 roll CompB exch
      i 2 eq {
%    \end{macrocode}
% check also the first plane
%    \begin{macrocode}
        4 copy 4 2 roll AdjustRelRot
      } if
      AdjustRelRot
    } {
%    \end{macrocode}
% check if the first plane is an NodeIfc and correct its rotation, the
% node ordering in CompA is irrelevant at this point, so we use desc.
%    \begin{macrocode}
      i 2 eq {
        CompB amb CompA desc AdjustRelRot
      } if
      pop amb dup
    } ifelse
    CompB /CompA CompB def
    counttomark 2 roll
  } for pop
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{AdjustRelRot}
%   Adjusts the relative orientation of \PSstring{CompB} based on the
%   relative connection between \PSstring{CompA} and \PSstring{CompB}.
%   \begin{pssyntax}
%     \PSstring{CompA} \PSvar{desc|asc} \PSstring{CompB} \PSvar{desc|asc} \PSop{AdjustRelRot}
%   \end{pssyntax}
%    \begin{macrocode}
/AdjustRelRot {
  (AdjustRelRot) DebugBegin
  exch dup cvn load /adjustRel known {
    dup dup 4 2 roll isAmbiguous { 
      exch pop (C)
    }{ 
      desc eq { (N) }{ 1 } ifelse 
    } ifelse 
    exch GetIfcCenter 5 3 roll
    exch dup 3 1 roll isAmbiguous { 
      pop (C)
    }{ 
      desc eq { 1 }{ (N) } ifelse 
    } ifelse 
    exch GetIfcCenter
    @ABVect exch atan exch
    cvn load begin
      adjustRel {
        matrix rotate CompMtrx matrix concatmatrix /CompMtrx ED
        /adjustRel false def
      } {
        pop
      } ifelse
    end
  } {
    pop pop pop pop
  } ifelse
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{PushAllPlanesOnStack}
%   \begin{pssyntax}
%     \PSvar{[} \PSvar{desc|asc} \PSstring{CompN} \PSvar{\ldots} \PSvar{desc|asc} \PSstring{Comp1} 
%     \PSop{PushAllPlanesOnStack}
%     \PSvar{[} \PSproc{PN \PSstring{CompName} n mode draw?} \PSvar{\ldots{}}
%   \end{pssyntax}
%   \begin{psarglist}
%     \psargitem{PN} The number of the plane of the component \PSstring{CompNameN}, can be an integer or a string.
%     \psargitem{CompName} The name of the component which the interface \PSvar{PN} belongs to.
%     \psargitem{n} The refractive index after the respective interface.
%     \psargitem{mode} Specifies if the interface is transmittive (\PSvar{trans}) or reflective (\PSvar{refl}).
%     \psargitem{draw?} Specifies if the connection to this interface should be drawn or if the current point is only moved.
%   \end{psarglist}
%    \begin{macrocode}
/PushAllPlanesOnStack {
  (PushAllPlanesOnStack) DebugBegin
  counttomark 2 div cvi /@N ED
  1 1 @N {
%    \end{macrocode}
% iterate over all components
%    \begin{macrocode}
    /last false def
    /first false def
    dup 1 eq {
      /first true def pop beaminsidefirst
    } {
      @N eq {
        beaminsidelast
        /last true def
      } {
        beaminside
      } ifelse
    } ifelse 
    exch load dup dup 
    /forcebeaminside get {
      3 -1 roll pop true
    } {
      dup /allowbeaminside get 4 -1 roll and 
    } ifelse
    /drawinside ED
    /ambiguous get {
      /name get drawinside [ 3 1 roll ]
      counttomark 1 roll pop
    } {
      begin
%    \end{macrocode}
% Start of the component dict.
%    \begin{macrocode}
        desc eq {
          N N -1 1 1
        } {
          1 1 1 N N
        } ifelse
        first startinside not and {
%    \end{macrocode}
% first comp and we do not start inside
%    \begin{macrocode}
          5 -2 roll
          pop pop
          2 copy 5 2 roll
        } if
        5 1 roll
        {
%    \end{macrocode}
% iterate over all planes
%    \begin{macrocode}
          3 1 roll 2 copy 5 -1 roll
          dup 3 1 roll
          eq first not and {
%    \end{macrocode}
% always draw the line to the first plane of a component
%    \begin{macrocode}
            true
          } {
%    \end{macrocode}
% the other beams depend on some options
%    \begin{macrocode}
            drawinside
          } ifelse
          exch dup 4 -1 roll eq {
%    \end{macrocode}
% after the last component plane we have always air
%    \begin{macrocode}
            bgRefIndex
          }{
%    \end{macrocode}
% otherwise the respective refractive index of the component
%    \begin{macrocode}
            name GetRefIndex
          } ifelse
          exch dup N eq {
            pop (N)
          } {
            inttostr
          } ifelse exch
          3 1 roll name
          4 1 roll
          dup IfcName load /mode get
          3 1 roll 5 1 roll
          [ 6 1 roll ] cvx counttomark 1 roll
          last {
            savebeampoints 1 ge stopinside not and
            savebeampoints 1 lt beaminsidelast not and or {
              exit
            } if
          } if
        } for pop pop
      end
    } ifelse
  } for
  DebugEnd
  counttomark 1 eq { pop } if
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{IfcName}
% Construct the interface name from \PSvar{num}. This must be called within a dict of a
% optexpcomp, because the last node ends with (N) instead of the number and we must
% know the number of component interfaces.
% \begin{pssyntax}
% \PSvar{num} \PSop{IfcName} \PSname{P@num}
% \end{pssyntax}
%    \begin{macrocode}
/IfcName {
  dup dup 1 eq not exch N eq and {
    pop (N)
  } {
    inttostr
  } ifelse
  (P@) exch strcat cvn
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{GetIfcMode}
%   \begin{pssyntax}
%     \PSstring{name} \PSvar{num} \PSop{GetIfcMode} \PSvar{mode}
%   \end{pssyntax}
%    \begin{macrocode}
/GetIfcMode {
  exch cvn load begin
    IfcName load /mode get
  end
} bind def
%    \end{macrocode}
% \end{macro}
% \begin{macro}{NodeName}
% Construct the plane name from IfcNum. This must be called within a dict of a
% optexpcomp, because the last node ends with (N) instead of the number and we must
% know the plane count of the component.
% \begin{pssyntax}
% \PSstring{name} \PSvar{num} \PSop{NodeName} \PSname{N@namenum}
% \end{pssyntax}
%    \begin{macrocode}
/NodeName {
  dup /stringtype eq not { inttostr } if
  strcat (N@) exch strcat cvn
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{OrderNodes}
%   Check if node (\PSvar{XB1}, \PSvar{YB1}) or (\PSvar{XBN}, \PSvar{YBN}) is nearer to node (\PSvar{XA}, \PSvar{YA}). If it
%   \PSvar{B1} is nearer, push \PSvar{asc} on the stack, otherwise
%   \PSvar{desc}. If \PSvar{calcDist} is \opt{true} it leaves also the actual
%   smallest distance on the stack.
%   \begin{pssyntax}
%     \PSvar{XA YA XB1 YB1 XBN YBN calcDist} \PSop{OrderNodes} \PSvar{desc|asc} \PSvar{distance}
%   \end{pssyntax}
%    \begin{macrocode}
/OrderNodes {
   7 1 roll 6 -2 roll 2 copy 8 2 roll
   @ABDist 5 1 roll @ABDist 2 copy gt {
       pop asc exch
   } {
       exch pop desc exch
   } ifelse
   3 -1 roll not {
       pop
   } if
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{NormalVec}
%   Construct a normal vector $\vec{n}$ to the plane such that its
%   scalar product with the incomping wave vector $\vec{v}_\text{in}$ is
%   negative: $\vec{n}\cdot (-\vec{v}_\text{in}) > 0$.
%   \begin{pssyntax}
%     \PSvar{Xin Yin Xplane Yplane} \PSop{NormalVec} \PSvar{Xnorm Ynorm}
%   \end{pssyntax}
%    \begin{macrocode}
/NormalVec {
  neg exch 2 copy 6 2 roll DotProd 0 gt {
    -1 mul exch -1 mul exch
  } if
  NormalizeVec
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{DotProd}
% Scalar product between two vectors.
% \begin{pssyntax}
%   \PSvar{Xa Ya Xb Yb} \PSop{DotProd} \PSvar{val}
% \end{pssyntax}
%    \begin{macrocode}
/DotProd {
    3 -1 roll mul 3 1 roll mul add
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{VecAngle}
% Angle between two vectors $\cos(\alpha) = \frac{ab}{|a||b|}$
% \begin{pssyntax}
%   \PSvar{Xa Ya Xb Yb} \PSop{VecAngle} \PSvar{angle}
% \end{pssyntax}
%    \begin{macrocode}
/VecAngle {
  4 copy 4 copy DotProd 5 1 roll 
  tx@Dict begin 
    Pyth 3 1 roll Pyth 
  end mul 
  div Acos
  5 2 roll mul 4 1 roll 3 -1 roll mul 3 -1 roll sub 
  0 le { -1 }{ 1 } ifelse mul
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{VecAdd}
% Addition of two vectors.
% \begin{pssyntax}
%   \PSvar{Xa Ya Xb Yb} \PSop{VecAdd} \PSvar{Xa+Xb Ya+Yb}
% \end{pssyntax}
%    \begin{macrocode}
/VecAdd {
    3 -1 roll add 3 1 roll add exch
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{VecScale}
% Scale a vector by a factor \PSvar{fac}.
% \begin{pssyntax}
%   \PSvar{Xa Ya fac} \PSop{VecScale} \PSvar{fac}$\cdot$\PSvar{Xa} \PSvar{fac}$\cdot$\PSvar{Ya}
% \end{pssyntax}
%    \begin{macrocode}
/VecScale {
  dup 4 -1 roll mul 3 1 roll mul
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{ToVec}
%   Convert two numbers to a procedure holding the two values. This
%   representation is used to save coordinate values of nodes and vectors.
%   \begin{pssyntax}
%     \PSvar{X Y} \PSop{ToVec} \PSproc{X Y}
%   \end{pssyntax}
%    \begin{macrocode}
/ToVec {
    [ 3 1 roll ] cvx
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{AngToVec}
%   Convert an angle to the related vector representation (normalized). The
%   angle is with respect to the positive $x$-axis.
% \begin{pssyntax}
%   \PSvar{angle} \PSop{AngToVec} \PSproc{X Y}
%   \end{pssyntax}
%    \begin{macrocode}
/AngToVec {
    dup cos exch sin ToVec
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{NormalizeVec}
% Normalize a vector ($X'^2 + Y'^2 = 1$)
% \begin{pssyntax}
%   \PSvar{X Y} \PSop{NormalizeVec} \PSvar{X' Y'}
% \end{pssyntax}
%    \begin{macrocode}
/NormalizeVec {
  2 copy
  tx@Dict begin
    Pyth
  end
  dup 3 1 roll div 3 1 roll div exch
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{@ABVect}
% \begin{pssyntax}
%   \PSvar{Xa Ya Xb Yb} \PSop{@ABVect} \PSvar{dX dY}
% \end{pssyntax}
%    \begin{macrocode}
/@ABVect { 
  3 -1 roll exch sub 3 1 roll sub exch
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{@ABDist}
% \begin{pssyntax}
%   \PSvar{Xa Ya Xb Yb} \PSop{@ABDist} \PSvar{dist}
% \end{pssyntax}
%    \begin{macrocode}
/@ABDist { 
  3 -1 roll sub dup mul 3 1 roll sub dup mul add sqrt 
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{@InterLines}
%   Shorthand definition for \PSvar{InterLines} procedure of the
%   \nxLPack{pst-eucl} package. Takes care of a bug in the
%   \nxLPack{pst-eucl} package, that too many items are popped off the
%   stack if no intersection point exists.
% \begin{pssyntax}
%   \PSvar{X1 Y1 X2 Y2 X3 Y3 X4 Y4} \PSop{@InterLines} \PSvar{X Y ret}
% \end{pssyntax}
%    \begin{macrocode}
/@InterLines {
  tx@EcldDict begin
    EqDr /D1c exch def /D1b exch def /D1a exch def
    EqDr /D2c exch def /D2b exch def /D2a exch def
    D1a D2b mul D1b D2a mul sub dup 
    ZeroEq { % parallel lines
      pop 0 0 missed 
    }{
      /Det exch def
      D1b D2c mul D1c D2b mul sub Det div
      D1a D2c mul D2a D1c mul sub Det div
      ok
    } ifelse  
  end
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{@GetCenter}
%   Shorthand definition for the \PSvar{GetCenter} procedure of the
%   \nxLPack{pst-node} package. Takes either a string or a literal name
%   for the node name \PSvar{name}.
%   \begin{pssyntax}
%     \PSname{name} \PSop{@GetCenter} \PSvar{X Y}
%   \end{pssyntax}
%    \begin{macrocode}
/@GetCenter { 
  tx@NodeDict begin load GetCenter end 
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{@NewNode}
% Shorthand definition for creating a new pnode.
%    \begin{macrocode}
/@NewNode {
  tx@NodeDict begin 
    false exch 10 {InitPnode } NewNode 
  end
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{RefractVec}
%   Calculate the refracted vector, the normal plane vector must be
%   constructed with \PSvar{NormVec}, see
%   \url{http://en.wikipedia.org/wiki/Snell%27s_law#Vector_form} for the
%     formulas.
%     \begin{pssyntax}
%       \PSvar{Xin Yin Xnorm Ynorm n1 n2} \PSop{RefractVec} \PSvar{Xout Yout}
%     \end{pssyntax}
%  If it would be total internal reflection, the output vector is (0, 0).
%    \begin{macrocode}
/RefractVec {
  (RefractVec) DebugBegin
  TransformRefIndex exch TransformRefIndex exch div /n ED 
  /Ynorm ED /Xnorm ED
  NormalizeVec /Yin ED /Xin ED 
  n abs 1 eq {
    Xin Yin
  }{
    /costheta1 Xnorm Ynorm Xin neg Yin neg DotProd def
    1 n dup mul 1 costheta1 dup mul sub mul sub
    dup 0 lt {
%    \end{macrocode}
% would be total internal reflection, stop
%    \begin{macrocode}
      pop 0 0
    } {
      sqrt /costheta2 ED
      n Xin mul n Yin mul 
      n costheta1 mul costheta2 sub dup 
      Xnorm mul exch Ynorm mul VecAdd
    } ifelse
  } ifelse
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{ReflectVec}
%   Calculate the reflected vector, the normal plane vector must be
%   constructed with \PSvar{NormVec}.
%   \begin{pssyntax}
%     \PSvar{Xin Yin Xnorm Ynorm} \PSop{ReflectVec} \PSvar{Xout Yout}
%   \end{pssyntax}
%    \begin{macrocode}
/ReflectVec {
  (ReflectVec) DebugBegin
  /Ynorm ED /Xnorm ED NormalizeVec /Yin ED /Xin ED
  /costheta1 Xnorm Ynorm Xin neg Yin neg DotProd def
  Xin Yin 2 costheta1 mul dup Xnorm mul exch Ynorm mul VecAdd
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{CurvedInterface}
%   \begin{pssyntax}
%     \PSvar{Xp Yp Xr Yr} \PSop{CurvedInterface} \PSvar{X0' Y0' Xout Yout status}
%   \end{pssyntax}
%    \begin{macrocode}
/CurvedInterface {
  (CurvedInterface) DebugBegin
  2 copy /Yr ED /Xr ED 
  tx@Dict begin Pyth end /radius ED /Yp ED /Xp ED
  /X0n X0 Xp sub def /Y0n Y0 Yp sub def
  tx@EcldDict begin
    X0n Y0n 2 copy 2 copy Xin 3 -1 roll add Yin 3 -1 roll add
    2 copy 6 2 roll EqDr radius InterLineCircle
  end
  4 copy
  0 eq 3 {exch 0 eq and} repeat {
%    \end{macrocode}
% if all coordinates are zero we missed the circle, stop
%    \begin{macrocode}
    missed
  } {
    4 copy
%    \end{macrocode}
% Chose which of the two intersection points to take.
%    \begin{macrocode}
    Xr neg Yr neg 2 copy
    8 -2 roll @ABDist
    5 1 roll @ABDist
    gt {
%    \end{macrocode}
% «dist from first point» $>$ «dist from second point», take second point.
%    \begin{macrocode}
      4 2 roll
    } if pop pop
    Xp Yp VecAdd
    2 copy Xp Yp 4 2 roll @ABVect exch neg Xin Yin 4 2 roll NormalVec 
    Xin Yin 4 2 roll
%    \end{macrocode}
% on stack: crossing point, in vector, and normal vector
%    \begin{macrocode}
    mode trans eq {
      n1 n2 RefractVec
      2 copy 0 eq exch 0 eq and { tir } { ok } ifelse
    } {
      ReflectVec ok
    } ifelse /n1 n2 def
    5 -2 roll 2 copy 7 2 roll X0 Y0 @ABVect Xin Yin DotProd 0 lt 
    PN 1 gt and {
      pop missed
    } if
  } ifelse
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{PlainInterface}
%   \begin{pssyntax}
%     \PSvar{Xp Yp dXp dYp} \PSop{PlainInterface} \PSvar{X0' Y0' Xout Yout status}
%   \end{pssyntax}
%    \begin{macrocode}
/PlainInterface {%
  (PlainInterface) DebugBegin
  /dYp ED /dXp ED /Yp ED /Xp ED
  Xp Yp Xp dXp add Yp dYp add X0 Y0 X0 Xin add Y0 Yin add 
  @InterLines missed eq {
    0 0 missed
  } {
    Xin Yin Xin Yin dXp dYp NormalVec
    mode trans eq {
      n1 n2 RefractVec
      2 copy 0 eq exch 0 eq and { tir } { ok } ifelse
    } {
      ReflectVec ok
    } ifelse /n1 n2 def
    5 -2 roll 2 copy 7 2 roll X0 Y0 @ABVect Xin Yin DotProd 0 lt 
    PN 1 gt and {
      pop missed
    } if
  } ifelse
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
% 
% 
% \begin{macro}{TransformRefIndex}
%   If the refractive index on the stack is for the background (has value
%   \opt{bgRefIndex}, which is \opt{0}), we replace it here with its actual
%   value (\opt{1}). This is necessary to distinguish between background index
%   and components having an index of \opt{1}, which can be changed with option
%   \opt{n}.
%   \begin{pssyntax}
%     \PSvar{n} \PSop{TransformRefIndex} \PSvar{n|1}
%   \end{pssyntax}
%    \begin{macrocode}
/TransformRefIndex {
  dup bgRefIndex eq { pop 1 } if
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{GetRefIndex}
% Evaluate the refractive index of component \opt{name}.
% \begin{pssyntax}
%   \PSstring{name} \PSop{GetRefIndex} \PSvar{neval}
% \end{pssyntax}
%    \begin{macrocode}
/GetRefIndex {
  cvn load /n get /nbeam load exch
  EvalRefIndex
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{EvalRefIndex}
%   Evaluate the expression in \opt{nbeam} after setting refractive index to
%   \opt{n}.
%   \begin{pssyntax}
%     \PSproc{nbeam} \PSvar{n} \PSop{GetRefIndex} \PSvar{neval}
%   \end{pssyntax}
%    \begin{macrocode}
/EvalRefIndex {
  dup bgRefIndex eq not {
    1 dict begin 
%    \end{macrocode}
% Store \opt{n} locally for evaluation of the mathematical expression in
% \opt{nbeam}.
%    \begin{macrocode}
      /n ED
      exec
    end
  } if
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{Sellmaier}
%   Calculate the refractive index for BK7 glass with the Sellmaier
%   equation. The wavelength must be given in nanometre. The coefficients are
%   taken from \href{http://en.wikipedia.org/wiki/Sellmeier_equation}.
%   \begin{pssyntax}
%     \PSvar{lambda} \PSop{Sellmaier} \PSvar{n}
%   \end{pssyntax}
%    \begin{macrocode}
/Sellmaier {
  dup mul
  dup dup 1.03961212 mul exch 6000.69867 sub div
  exch dup dup 0.231792344 mul exch 20017.9144 sub div
  exch dup 1.01046945 mul exch 103.560653e6 sub div
  add add 1 add sqrt
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{TangentCrosspoint}
% Xp Yp Xt1 Yt1 Xt2 Yt2
%    \begin{macrocode}
/TangentCrosspoint {
    4 copy 4 copy 14 -2 roll 2 copy
    6 2 roll @ABVect neg exch
    6 2 roll @ABVect neg exch
    8 -2 roll VecAdd 10 2 roll VecAdd
    @InterLines pop
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{NearestNodeTmp}
% {NodeB} CompA -> shortest distance, planenum
%    \begin{macrocode}
/NearestNodeTmp {
  exch /NodeB ED
  /dist -1 def
  dup cvn load /N get dup 1 eq {
    [ exch (N) ]
  } {
    [ exch 1 1 3 -1 roll { } for ]
  } ifelse
  {
    2 copy pop 
    GetIfcCenterCorr 2 copy
    NodeB @ABDist
    dist 0 lt {
      /dist ED
      ToVec /node ED
    } {
      dup dist lt {
        /dist ED
        ToVec /node ED
      } {
        pop pop pop
      } ifelse
    } ifelse
  } forall
  pop dist /node load
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{NearestNode}
%   Get the coordinates of the node of \PSvar{CompA} which is nearest to
%   \PSvar{CompB}/\PSvar{NodeB}, or push the coordinates of
%   \PSvar{NodeA} on stack if it is already a node.
%   \begin{pssyntax}
%     \PSvar{CompA/NodeA} \PSvar{CompB/NodeB} \PSop{NearestNode} \PSvar{X Y}
%   \end{pssyntax}
%    \begin{macrocode}
/NearestNode {
  (NearestNode) DebugBegin
  dup xcheck not { nametostr } if /CompB ED
  dup xcheck not {
%    \end{macrocode}
% CompA is a component
%    \begin{macrocode}
    nametostr /CompA ED
    /CompB load dup xcheck not {
%    \end{macrocode}
% CompB is a component
%    \begin{macrocode}
      /mindist -1 def
      [ exch false GetInternalNodeNames ]
      { @GetCenter ToVec
        CompA NearestNodeTmp 
        exch dup mindist ge mindist 0 ge and { 
          pop pop 
        }{ 
          /mindist ED /minnodeA ED 
        } ifelse
      } forall
      minnodeA
    } {
      CompA NearestNodeTmp exch pop exec
    } ifelse
  } {
%    \end{macrocode}
% else, it is a node and we already have the appropriate coordinates on the
% stack
%    \begin{macrocode}
    exec
  } ifelse
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{RelFiberAngle}
% Calculate start angle of \cs{nccurve} from CompA to CompB
%
% \begin{pssyntax}
%   \PSvar{Xb Yb Xa Ya A B} \PSvar{fiberalign} \PSop{RelFiberAngle} \PSvar{angle}
% \end{pssyntax}
%    \begin{macrocode}
/RelFiberAngle {
  (RelFiberAngle) DebugBegin
  /fiberalign ED
  dup xcheck not { nametostr } if /CompB ED
  dup xcheck not { nametostr } if /CompA ED
  /CompA load xcheck {
    /CompB load xcheck {
%    \end{macrocode}
%  both parameters are nodes, so the angle is that of the direct connection line.
%    \begin{macrocode}
      @ABVect exch atan
    } {
%    \end{macrocode}
% B is a component, and A is a node: the angle at node A is calculated through component B
%    \begin{macrocode}
      4 copy @ABVect 6 2 roll pop pop 2 copy
%    \end{macrocode}
% on stack: Xb-Xa Yb-Ya Xb Yb Xb Yb
%    \begin{macrocode}
      CompB (Center) NodeName @GetCenter 
%    \end{macrocode}
% on stack: Xb-Xa Yb-Ya Xb Yb Xb Yb Xbc Ybc
%    \begin{macrocode}
      4 2 roll @ABVect 4 2 roll
      CompB 
      fiberalign center eq {
        RelFiberAngle@center
      }{
        3 1 roll pop pop
        RelFiberAngle@ref
      } ifelse
      2 copy exch atan
      7 3 roll 2 copy 9 -2 roll
      DotProd 0 gt 5 1 roll DotProd 0 gt xor { 180 add } if
    } ifelse
  } {
%    \end{macrocode}
% A is a component, B is insignificant
%
% discard coordinates of B
%    \begin{macrocode}
    4 2 roll pop pop 2 copy
    CompA (Center) NodeName @GetCenter
    4 2 roll @ABVect 4 2 roll
%    \end{macrocode}
% on stack: Xac-Xa Yac-Xa Xa Ya
%    \begin{macrocode}
    CompA fiberalign center eq {
      RelFiberAngle@center
    }{
      3 1 roll pop pop
      RelFiberAngle@tref
    } ifelse
    2 copy exch atan
%    \end{macrocode}
% Xac-Xa Yac-Ya XaB-XaA YaB-YaA angleTrefline
%    \begin{macrocode}
    5 1 roll DotProd 0 gt { 180 add } if
  } ifelse
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{/RelFiberAngle@ref}
% Calculate the vector of the reference line of \PSvar{CompA}.
% \begin{pssyntax}
%   \PSstring{CompA} \PSop{RelFiberAngle@ref} \PSvar{dX dY}
% \end{pssyntax}
%    \begin{macrocode}
/RelFiberAngle@ref {
  dup (A) NodeName exch (B) NodeName
  @GetCenter 3 -1 roll @GetCenter @ABVect 
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{/RelFiberAngle@tref}
% Same as \PSname{RelFiberAngle@ref} but uses the transformed reference nodes.
% \begin{pssyntax}
%   \PSvar{CompA} \PSop{RelFiberAngle@ref} \PSvar{dX dY}
% \end{pssyntax}
%    \begin{macrocode}
/RelFiberAngle@tref {
  dup (TrefA) NodeName exch (TrefB) NodeName
  @GetCenter 3 -1 roll @GetCenter @ABVect 
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{/RelFiberAngle@center}
%   Calculate the vector from the center node of \PSvar{CompA} to the
%   node \PSstring{Xa, Ya}.
% \begin{pssyntax}
%   \PSvar{Xa Ya CompA} \PSop{RelFiberAngle@center} \PSvar{dX dY}
% \end{pssyntax}
%    \begin{macrocode}
/RelFiberAngle@center {
  (Center) NodeName @GetCenter 4 2 roll @ABVect
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{GetIfcOrNodeCoord}
%   \begin{pssyntax}
%     \PSstring{IfcNum} \PSstring{CompName}/\PSproc{node} \PSop{GetIfcOrNodeCoord} \PSvar{x y}
%   \end{pssyntax}
%    \begin{macrocode}
/GetIfcOrNodeCoord {
  dup xcheck {
    exch pop exec
  } {
    nametostr exch nametostr exch GetIfcCenter
  } ifelse
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{connectInterfaces}
%   \begin{pssyntax}
%     \PSproc{vec}
%   \end{pssyntax}
% InVec Center CenterTmp PrevMode relangle
%    \begin{macrocode}
/connectInterfaces {
  /relAngleTmp ED
  PN 2 eq {
%    \end{macrocode}
% initialize relAngle, the angle between plane connection and input vector
%    \begin{macrocode}
    pop @ABVect NormalizeVec 4 2 roll VecAngle /relAngleTmp ED
  } if
  PN 3 ge {
    trans eq {
%    \end{macrocode}
% previous plane was transmittive, recalculate the input vector
%    \begin{macrocode}
      @ABVect NormalizeVec 4 2 roll pop pop % remove Vec from stack
      relAngleTmp matrix rotate dtransform
      4 2 roll pop pop
    } {
%    \end{macrocode}
% else, the previous plane was reflective, recalculate relAngle
%    \begin{macrocode}
      @ABVect NormalizeVec 4 2 roll VecAngle /relAngleTmp ED
    } ifelse
  } if
  relAngleTmp
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{GetCompRange}
% \PSstring{basename} \PSvar{start stop} 
% \PSop{GetCompRange} \PSstring{basenamestart} \ldots\ \PSstring{basenamestop}
%    \begin{macrocode}
/GetCompRange {
  2 copy gt { 1 }{ -1 } ifelse 3 -1 roll
  { exch dup 3 -1 roll inttostr strcat exch} for
  pop
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{CorrectDipoleIfc}
%   For a dipole which has two interface nodes (1) and (N) which are very close
%   together ($\text{dist} < 10^{-7}$) or which coincide, the automatic angle
%   estimation of the fiber connections does not work properly. So these
%   interfaces are separated as less as possible so that the NearestNode
%   procedure estimates two different distances. The changed nodes are saved
%   only in the interface dictionaly as XCorr and YCorr. You must use these for
%   the fiber connections.
%   \begin{pssyntax}
%     \PSstring{node1} \PSstring{node2} \PSstring{basename} \PSop{CorrectDipoleIfc}
%   \end{pssyntax}
%    \begin{macrocode}
/CorrectDipoleIfc {
  (CorrectDipoleIfc) DebugBegin
  dup dup 3 copy
  8 -1 roll dup 9 1 roll NodeName exch 7 -1 roll dup 7 1 roll NodeName
  gsave
    tx@Dict begin 
      STV CP T
      exch @GetCenter 3 -1 roll @GetCenter
    end
  grestore
  4 copy @ABDist 1e-7 lt {
%    \end{macrocode}
% The two nodes are closer together than $10^{-7}$, correct that to avoid
% problems with the angle direction when drawing fibers.
%    \begin{macrocode}
    6 -1 roll
    gsave
      tx@Dict begin 
        STV CP T
        (TrefA) NodeName @GetCenter 7 -1 roll 
        (TrefB) NodeName @GetCenter 
      end
    grestore
    @ABVect NormalizeVec 2 copy
%    \end{macrocode}
% The floating-point precision of the Postscript interpreter is
% approximately 8 digits, so in order to have an effect, the nodes must
% be separated by $10^{-7}$ times the maximum coordinate value.
%    \begin{macrocode}
    8 -2 roll abs exch abs mymax -1e-6 mul VecScale
    8 -2 roll cvn load begin
      IfcName load begin 
        X Y VecAdd /YCorr exch def /XCorr exch def
      end
    end
    4 2 roll abs exch abs mymax 1e-6 mul VecScale
    4 2 roll cvn load begin
      IfcName load begin
        X Y VecAdd /YCorr exch def /XCorr exch def
      end
    end
  } {
    10 { pop } repeat
  } ifelse
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{mymax}
% For some reason Adobe Distiller crashes if 'max' operator is used with two floats which are very close (4e-5 in one case)
%    \begin{macrocode}
/mymax {
  2 copy lt { exch } if pop
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{debug}
%   Print out the last \opt{N} elements from the stack, checks for
%   stackunderflow. I \opt{N} is negative, the complete stack is
%   printed. Compared to the \PSvar{stack} operand, it prints the content of
%   procedures and array, which we use a lot.
%   \begin{pssyntax}
%     \PSvar{N} \PSop{debug}
%   \end{pssyntax}
%    \begin{macrocode}
/debug { 
  /@N ED count dup @N gt @N 0 ge and { pop @N } if 
  copy @N { == } repeat
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{debugComp}
% Print out all parameters and planes of the component \opt{compname}.
%   \begin{pssyntax}
%     \PSstring{compname} \PSop{debugComp}
%   \end{pssyntax}
%    \begin{macrocode}
/debugComp { 
  dup (debug comp ") exch strcat ("===============) strcat ==
  cvn load { 
    dup type /dicttype eq {
      (plane----------------) == 
      { == == } forall
      (-----------done) ==
      } { == } ifelse
      ==
  } forall
  (================== done) ==
} bind def
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
end % tx@OptexpDict
%    \end{macrocode}
%</prolog> 
% \Finale
% \endinput
%
%<*indexstyle>
headings_flag       1
heading_prefix   "\\textbf{"
heading_suffix   "}\n"
quote		'"'
level		'!'
actual          '='
preamble
  "\\begin{theindex}\n"
item_1
  "\\par\\leavevmode\\hangindent10pt\\makebox[15pt][l]{ -- }"
item_01
  "\\par\\leavevmode\\hangindent10pt\\makebox[15pt][l]{ -- }"
item_x1
  "\\par\\leavevmode\\hangindent10pt\\makebox[15pt][l]{ -- }"
item_2
  "\\par\\leavevmode\\hangindent20pt\\makebox[30pt][l]{ -- -- }"
item_12
  "\\par\\leavevmode\\hangindent20pt\\makebox[30pt][l]{ -- -- }"
item_x2
  "\\par\\leavevmode\\hangindent20pt\\makebox[30pt][l]{ -- -- }"
%</indexstyle>
