% \iffalse meta-comment
%
% Copyright (C) 2007-2022 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>
    [2022/02/26 v6.1 Optical experimental setups with PSTricks]
%</stylefile>
%
%<*driver>
\documentclass[
paper=a4,
headinclude=false,
footinclude=false,
oneside,
toc=index,
headsepline,
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[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}
\usepackage{scrhack}
\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},
  alsoletter={12},
  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},
  moretexcs = [20]{lens, optbox, oenode, oenodeIn, oenodeExt, oenodeOut,
    oenodeRefA, oenodeRefB, oenodeTrefA, oenodeTrefB, oenodeLabel,
    oenodeRotref, oenodeBeam, oenodeBeamUp, oenodeBeamLow, oenodeCenter,
    oenodeIfc, oeBeamVec, oeBeamVecUp, oeBeamVecLow, oeBeamVecMedian,
    oeBeamCenter, optplate, optretplate, pinhole, crystal, optdetector,
    optdiode, doveprism, glanthompson, polarization, mirror, parabolicmirror, 
    oapmirror, axicon, optwedge, asphericlens,
    beamsplitter, optgrating, optprism, rightangleprism, pentaprism, optaom,
    optdipole, opttripole, optfiber, optamp, optmzm, optfilter, optsource,
    polcontrol, optisolator, optswitch, fiberdelayline,
    optfiberpolarizer, fibercollimator, optcoupler, wdmcoupler,
    wdmsplitter, optcirculator, fiberbox, eleccoupler, elecsynthesizer,
    elecmixer, optarrowcomp, optbarcomp, transmissiongrating, drawbeam, drawwidebeam,
    drawfiber, drawwire, frontlayer, backlayer, newOptexpDipole,
    newOptexpTripole, newOptexpFiberDipole, newOptexpComp,
    newOptexpFiberComp, 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,markcase=ignorenouppercase]{scrlayer-scrpage}
\pagestyle{scrheadings}
\clearmainofpairofpagestyles
\clearplainofpairofpagestyles
\ohead{\pagemark}
\ihead{\headmark}
\ofoot[\pagemark]{}
\automark[subsection]{section}
\setkomafont{headsepline}{\color{DOrange}}
\DeclareTOCStyleEntry[level=0, numwidth=2.0em]{default}{chapter}
\DeclareTOCStyleEntry[level=1, indent=1.5em, numwidth=3.0em]{default}{section}
\DeclareTOCStyleEntry[level=2, indent=3.8em, numwidth=4.0em]{default}{subsection}
\makeatletter
\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 @\ifodd
      \ifcsname r@comp:#1\endcsname 1\else
        \ifcsname r@prm:#1\endcsname 1\else 
          \ifcsname r@cs:#1\endcsname 1\else
            \ifcsname r@sty:#1\endcsname 1\else 0
      \fi\fi\fi\fi second\else first\fi oftwo\endcsname
}% \ifrefundefined
\def\lsthk@OutputBox@H@@k{%
    \begingroup%
      \let\lst@UM\@empty%
      \edef\@tempc{\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@%
        \ifcsdef{r@prm:\hyperlistingsreference}%
          {\hyperref[prm:\hyperlistingsreference]{\xLkeyword{\hyperlistingsreference}\boxframe{\wd\@tempboxa}{\ht\@tempboxa}{\dp\@tempboxa}}}%
          {\ifcsdef{r@comp:\hyperlistingsreference}%
            {\hyperref[comp:\hyperlistingsreference]{\xLcomp{\hyperlistingsreference}\boxframe{\wd\@tempboxa}{\ht\@tempboxa}{\dp\@tempboxa}}}%
            {\ifcsdef{r@sty:\hyperlistingsreference}%
              {\hyperref[sty:\hyperlistingsreference]{\xLstyle{\hyperlistingsreference}\boxframe{\wd\@tempboxa}{\ht\@tempboxa}{\dp\@tempboxa}}}%
              {\hyperref[cs:\hyperlistingsreference]{\xLcs{\hyperlistingsreference}\boxframe{\wd\@tempboxa}{\ht\@tempboxa}{\dp\@tempboxa}}}}}}%
      \unhbox\@tempboxa%
    \egroup%
}% \hyperlistings
\let\lsthk@OutputBox\lsthk@OutputBox@H@@k

\renewenvironment*{ltxsyntax}
  {\list{}{%
     \setlength{\labelwidth}{\marglistwidth}%
     \setlength{\labelsep}{0pt}%
     \setlength{\leftmargin}{0pt}%
     \renewcommand*{\makelabel}[1]{%
       \hss\ltxsyntaxfont\ltxsyntaxlabelfont##1}}%
   \let\cmditem\POE@cmditem
   \let\envitem\ltd@envitem
   \let\compitem\POE@compitem}
  {\endlist}

\newenvironment*{stylelist}
  {\list{}{%
     \setlength{\labelwidth}{\marglistwidth}%
     \setlength{\labelsep}{0.5\marglistsep}%
     \setlength{\leftmargin}{0pt}%
     \renewcommand*{\makelabel}[1]{\hss\optionlistfont##1}}%
     \let\styleitem\POE@styleitem
     \let\typeitem\POE@typeitem}%
  {\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
  \let\typeitem\POE@typeitem}

\def\POE@styleitem{%
  \@ifnextchar[%]
    {\POE@styleitem@i}
    {\POE@styleitem@i[]}}
\def\POE@styleitem@i[#1]#2{%
  \item[{#2}]%
  \label{sty:#2}\xdefLstyle{#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-1em\relax
  \else
    \@tempdima=\dimexpr\linewidth-\@tempdimb-1em\relax
  \fi
  \ifblank{#1}{}{\hfill\parbox[t]{\@tempdima}{\raggedleft default:~\ltd@textverb{#1}}}%
  \par\endgroup}

\def\POE@typeitem#1#2{%
  \item[{#1}]%
  \label{prm:#1}\docindexdef{#1=\nxLkeyword{#1}}%
  \begingroup\raggedright
  #2%
  \settowidth\@tempdimb{\prm{psstyle}}%
  \settowidth\@tempdimc{#1}%
  \@tempdimc=\dimexpr\@tempdimc+\labelsep-\labelwidth\relax
  \ifdim\@tempdimc>0pt%
    \@tempdima=\dimexpr\linewidth-\@tempdimb-\@tempdimc-1em\relax
  \else
    \@tempdima=\dimexpr\linewidth-\@tempdimb-1em\relax
  \fi
  \par\endgroup}

\def\POE@option#1#2#3{%
  \item[#1]%
  \begingroup\raggedright
  \ltd@textverb{=}%
  \settowidth\@tempdimb{\ltd@textverb{=}}%
  \settowidth\@tempdimc{#1}%
  \@tempdimc=\dimexpr\labelwidth-\@tempdimc\relax
  \ifdim\@tempdimc<0pt
    \@tempdima=\dimexpr\linewidth-\@tempdimb+\@tempdimc-2em\relax
  \else
    \@tempdima=\dimexpr\linewidth-\@tempdimb-2em\relax
  \fi
  \ifblank{#3}
    {}
    {\settowidth\@tempdimb{default: #3}%
     \@tempdima=\dimexpr\@tempdima-\@tempdimb-2em\relax}%
  \parbox[t]{\@tempdima}{\raggedright #2}%
  \ifblank{#3}
    {}
    {\hfill default:~#3}%
  \par\endgroup
  \nobreak\vspace{\itemsep}}

\def\POE@optitem{%
  \@ifstar
    {\boolfalse{@tempswa}\POE@optitem@i}
    {\booltrue{@tempswa}\POE@optitem@i}}
\newcommand*{\POE@optitem@i}[3][]{%
  \ifbool{@tempswa}%
    {\label{prm:#2}\xdefLkeyword{#2}}%
    {\xLkeyword{#2}}%
  \ifblank{#1}
    {\POE@option{#2}{#3}{}}
    {\POE@option{#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}\xdefLkeyword{#2}}%
    {\xLkeyword{#2}}%
  \ifblank{#1}
    {\POE@option{#2}{\prm{#3}}{}}
    {\POE@option{#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}\xdefLkeyword{#2}}%
    {\xLkeyword{#2}}%
  \ifblank{#1}
    {\POE@option{#2}{\ltd@verblist{#3}}{}}
    {\POE@option{#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}\xdefLkeyword{#2}}%
    {\xLkeyword{#2}}%
  \ifblank{#1}
    {\POE@option{#2}{\ltd@verblist{true,false}}{}}
    {\POE@option{#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}\xdefLkeyword{#2}}%
    {\xLkeyword{#2}}%
  \ifblank{#1}
    {\POE@option{#2}{\prm{int}}{}}
    {\POE@option{#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}\xdefLkeyword{#2}}%
    {\xLkeyword{#2}}%
  \ifblank{#1}
    {\POE@option{#2}{\prm{num}}{}}
    {\POE@option{#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}\xdefLkeyword{#2}}%
    {\xLkeyword{#2}}%
  \ifblank{#1}
    {\POE@option{#2}{\prm{psnum}}{}}
    {\POE@option{#2}{\prm{psnum}}{\ltd@textverb{#1}}}}%

\def\ltd@csitem{%
  \@ifstar
    {\boolfalse{@tempswa}\ltd@csitem@i}
    {\booltrue{@tempswa}\ltd@csitem@i}}
\def\ltd@csitem@i#1{%
  \ifbool{@tempswa}
    {\ltd@item@ii{\textbackslash#1\hspace\marglistsep}{#1}}
    {\ltd@item@ii{\textbackslash#1\hspace\marglistsep}{}}}

\def\POE@cmditem{%
  \@ifstar
    {\boolfalse{@tempswa}\POE@cmditem@i}
    {\booltrue{@tempswa}\POE@cmditem@i}}
\def\POE@cmditem@i#1{%
  \ifbool{@tempswa}
    {\POE@cmditem@ii{\textbackslash#1}{cs:#1}}
    {\POE@cmditem@ii{\textbackslash#1}{}}}
\def\POE@compitem{%
  \@ifstar
    {\boolfalse{@tempswa}\POE@compitem@i}
    {\booltrue{@tempswa}\POE@compitem@i}}
\def\POE@compitem@i#1{%
  \ifbool{@tempswa}
    {\POE@cmditem@ii{\textbackslash#1}{comp:#1}}
    {\POE@cmditem@ii{\textbackslash#1}{}}}
\def\POE@cmditem@ii#1#2{%
  \ltd@itemsave
  \ifhmode
    \itemsep-\topsep
  \else
    \ltd@itembreak
  \fi
  \item[#1]%
  \ltd@itemrest
  \ifblank{#2}{}{\label{#2}}%
  \begingroup
  \ltd@syntaxsetup
  \ltxsyntaxfont
  \let\@tempa\@empty
  \ltd@parseargs}

\def\ltd@csitem@ii#1#2{%
  \ltd@itemsave
  \ifhmode
    \itemsep-\topsep
  \else
    \ltd@itembreak
  \fi
  \item[#1]%
  \ltd@itemrest
  \ifblank{#2}{}{\label{cs:#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*{\compref}[1]{\ref{comp:#1}}
\newcommand*{\hyperpagedef}[1]{\textbf{\hyperpage{#1}}}
\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}}
\newcommand{\docindexdef}[1]{\sindex[doc]{#1|hyperpagedef}}
\makeatletter
\def\Lcs{\@ifstar{\Lcs@nobm}{\Lcs@bm}}
\def\Lcs@nobm#1{\nxLcs{#1}\xLcs{#1}}
\def\Lcs@bm#1{\hyperref[cs:#1]{\Lcs@nobm{#1}}}
\def\xLcs#1{\docindex{#1=\nxLcs{#1}}\docindex{\POEindexMacro!#1=\nxLcs{#1}}}
\def\nxLcs#1{\texttt{\textbackslash#1}}

\def\Lcomp{\@ifstar{\Lcomp@nobm}{\Lcomp@bm}}
\def\Lcomp@nobm#1{\nxLcomp{#1}\xLcomp{#1}}
\def\Lcomp@bm#1{\hyperref[comp:#1]{\Lcomp@nobm{#1}}}
\def\xLcomp#1{\docindex{#1=\nxLcomp{#1}}\docindex{\POEindexComp!#1=\nxLcomp{#1}}}
\def\nxLcomp#1{\texttt{\textbackslash#1}}

\def\LPack#1{\nxLPack{#1}\docindex{#1=\nxLPack{#1}}\docindex{\POEindexPack!#1=\nxLPack{#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=\nxLenv{#1}}\docindex{\POEindexEnv!#1=\nxLenv{#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{\nxLkeyword{#1}\xLkeyword{#1}}
\def\Lkeyword@bm#1{\hyperref[prm:#1]{\Lkeyword@nobm{#1}}}
\def\xLkeyword#1{\docindex{#1=\nxLkeyword{#1}}\docindex{\POEindexKeyword!#1=\nxLkeyword{#1}}}
\def\xdefLkeyword#1{\docindexdef{#1=\nxLkeyword{#1}}\docindexdef{\POEindexKeyword!#1=\nxLkeyword{#1}}}
\def\nxLkeyword#1{\texttt{#1}}

\def\xLoption#1{\docindex{#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{\nxLstyle{#1}\xLstyle{#1}}
\def\Lstyle@bm#1{\hyperref[sty:#1]{\Lstyle@nobm{#1}}}
\def\xLstyle#1{\docindex{#1=\nxLstyle{#1}}\docindex{\POEindexStyle!#1=\nxLstyle{#1}}}
\def\xdefLstyle#1{\docindexdef{#1=\nxLstyle{#1}}\docindexdef{\POEindexStyle!#1=\nxLstyle{#1}}}
\def\nxLstyle#1{\texttt{#1}}

\def\Ldipole#1{\nxLcs{#1}\xLdipole{#1}}
\def\xLdipole#1{\docindexdef{#1=\nxLcs{#1}}\docindexdef{\POEindexComp!#1=\nxLcs{#1}}}

\def\Ltripole#1{\nxLcs{#1}\xLtripole{#1}}
\def\xLtripole#1{\docindexdef{#1=\nxLcs{#1}}\docindexdef{\POEindexComp!#1=\nxLcs{#1}}}

\def\Lfdipole#1{\nxLcs{#1}\xLfdipole{#1}}
\def\xLfdipole#1{\docindexdef{#1=\nxLcs{#1}}\docindexdef{\POEindexComp!#1=\nxLcs{#1}}}

\def\Lfmultipole#1{\nxLcs{#1}\xLfmultipole{#1}}
\def\xLfmultipole#1{\docindexdef{#1=\nxLcs{#1}}\docindexdef{\POEindexComp!#1=\nxLcs{#1}}}

\def\Lemultipole#1{\nxLcs{#1}\xLemultipole{#1}}
\def\xLemultipole#1{\docindexdef{#1=\nxLcs{#1}}\docindexdef{\POEindexComp!#1=\nxLcs{#1}}}
\makeatother

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

\newcommand{\fiberdipoledesc}[1]{%
  \xLfdipole{#1}%
  \compitem{#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{\POEindexComp}{Komponenten}
%   \newcommand{\POEindexStyle}{Stile}
%   \newcommand{\POEindexMacro}{Makros}
%   \newcommand{\POEindexKeyword}{Parameter}
%   \newcommand{\POEindexEnv}{Umgebungen}
%   \newcommand{\POEindexPack}{Pakete}
%   \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{\POEindexComp}{components}
%   \newcommand{\POEindexStyle}{styles}
%   \newcommand{\POEindexMacro}{macros}
%   \newcommand{\POEindexKeyword}{parameters}
%   \newcommand{\POEindexEnv}{environments}
%   \newcommand{\POEindexPack}{packages}
%   \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,20.5)
%   \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{pstricks} ($\geq 2.53$), \LPack{pst-plot} ($\geq
%   1.6.1$), \LPack{pst-node}, \LPack{pstricks-add}, \LPack{multido},
%   \LPack{pst-eucl}, \LPack{pst-intersect} ($\geq 0.4$) 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{pstricks} ($\geq 2.53$), \LPack{pst-plot} ($\geq 1.61$),
%   \LPack{pst-node}, \LPack{multido}, \LPack{pstricks-add},
%   \LPack{pst-eucl}, \LPack{pst-intersect} ($\geq 0.4$) 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: David
% Carlisle, Florent Chervet, Enrico Gregorio, 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: David
% Carlisle, Florent Chervet, Enrico Gregorio, 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)
  \pnodes(0,1){A}(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
% \Lcomp{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
% \Lcomp{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
\begin{LTXexample}[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}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN\subsection{Galilei-Fernrohr}\fi
% \ifENGLISH\subsection{Galilean telescope}\fi
%
% \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
% \Lcomp{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
% \Lcomp{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, label=ex:galileo, caption={caption}]
*\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 \Lcomp{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 \Lcomp{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 \Lcomp{optbox} is originally a free-ray component, so that for it the
% fiber connection must be enabled with \Lkeyword{fiber}. The width of all
% \Lcomp{optbox} is changed to \opt{0.7}.
% \fi
% \iffalse
%<*ignore>
% \fi
% \begingroup
% \catcode`\*=13
% \def*{}%
\begin{LTXexample}[style=example, linerange={1-4,6-6}]
*\ON*\begin{pspicture}[showgrid](4.7,2)
  \pnodes(0.7,1){A}(1,1){B}(2.8,1){C}(4,1.5){D}(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-5,7-7}]
*\ON*\begin{pspicture}[showgrid](4.7,2)
  \pnodes(0.7,1){A}(1,1){B}(2.8,1){C}(4,1.5){D}(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-6,8-8}]
*\ON*\begin{pspicture}[showgrid](4.7,2)
  \pnodes(0.7,1){A}(1,1){B}(2.8,1){C}(4,1.5){D}(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 \Lcomp{optdetector} wird
% nach Voreinstellung 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 \Lcomp{optdetector} is set by default at the
% end of the reference line, it has \Lkeyword{position} preset 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-8,10-10}]
*\ON*\begin{pspicture}[showgrid](4.7,2)
  \pnodes(0.7,1){A}(1,1){B}(2.8,1){C}(4,1.5){D}(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}[caption={caption}, label={ex:fiber-setup-alt}, 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-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
%
% \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
%
% \iffalse
%<*ignore>
% \fi
\begingroup
\catcode`\*=13
\def*{}%
\begin{LTXexample}[style=example, hsep=8mm, numbers=left, numberstyle=\footnotesize, caption={caption}, label=ex:michelson]
\begin{pspicture}(3.2,5)
  \pnodes(0,3){A}(1,3){BS}(3,3){M1}(1,5){M2}(1,1){PD}*\label{l:ex2-nodes}*
  \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-nodes}) 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-nodes}) 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 .\ c relative}\fi
% \ifENGLISH This is an alias for \opt{label=0 .\ c 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)
  \pnodes(0.5,1){A}(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)
  \pnodes(0.5,1){A}(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 sollte nicht mehr verwendet werden, er ist
% äquivalent zu \Lkeyword{position}\opt{=end}.
% \fi
% \ifENGLISH This parameter should not be used any more, it 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}
% \psnumitem[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)
  \pnodes(0,1){A}(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)
  \pnodes(0,1){A}(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,10-10}, morekeywords={[21]{compshift}}]
\begin{pspicture}(4,2)
  \pnodes(0.4, 0.5){A}(3.6,0.5){B}
  \lens[lens=2 2 2, compshift=0.5](A)(B)
  \psline[style=Refline, linestyle=dashed](\oenodeRefA{})(\oenodeRefB{})
  \psdot(\oenodeRefA{})\uput[-90](\oenodeRefA{}){RefA}
  \psdot(\oenodeRefB{})\uput[-90](\oenodeRefB{}){RefB}
  \psdot[style=CenterNode](\oenodeIn{})
  \psdot[style=CenterNode](\oenodeOut{})
  \psline[linecolor=DOrange, arrows=|->, arrowscale=1.5, arrowinset=0](\oenodeCenter{}|A)(\oenodeCenter{})
\end{pspicture}
\end{LTXexample}
\begin{LTXexample}[linerange={1-3,9-9}, morekeywords={[21]{compshift}}]
\begin{pspicture}(4,2) 
  \pnodes(0.4,1.2){A}(3,0.2){B}
  \mirror[compshift=0.5](A)(B|A)(B)
  \psline[style=Refline, linestyle=dashed](\oenodeRefA{})(\oenodeRefB{}|\oenodeRefA{})(\oenodeRefB{})
  \psdot(\oenodeRefA{})\uput[-90](\oenodeRefA{}){RefA}
  \psdot(\oenodeRefB{})\uput[0](\oenodeRefB{}){RefB}
  \psdot[style=CenterNode](\oenodeIn{})
  \psline[linecolor=DOrange, arrows=|->, arrowscale=1.5, arrowinset=0](B|A)(\oenodeCenter{})
\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,10-10}, morekeywords={[21]{compoffset}}]
\begin{pspicture}(4,2)
  \pnodes(0.4, 1){A}(3.6, 1){B}
  \lens[lens=2 2 2, compoffset=0.5](A)(B)
  \psline[style=Refline, linestyle=dashed](\oenodeRefA{})(\oenodeRefB{})
  \psdot(\oenodeRefA{})\uput[-90](\oenodeRefA{}){RefA}
  \psdot(\oenodeRefB{})\uput[-90](\oenodeRefB{}){RefB}
  \psdot[style=CenterNode](\oenodeIn{})
  \psdot[style=CenterNode](\oenodeOut{})
  \psline[linecolor=DOrange, arrows=|->, arrowscale=1.5, arrowinset=0]([Xnodesep=-0.5]\oenodeCenter{})(\oenodeCenter{})
\end{pspicture}
\end{LTXexample}
\begin{LTXexample}[linerange={1-3,9-9}, morekeywords={[21]{compoffset}}]
\begin{pspicture}(4,2) 
  \pnodes(0.4,1.2){A}(3,0.2){B}
  \mirror[compoffset=0.5](A)(B|A)(B)
  \psline[style=Refline, linestyle=dashed](\oenodeRefA{})(\oenodeRefB{}|\oenodeRefA{})(\oenodeRefB{})
  \psdot(\oenodeRefA{})\uput[-90](\oenodeRefA{}){RefA}
  \psdot(\oenodeRefB{})\uput[0](\oenodeRefB{}){RefB}
  \psdot[style=CenterNode](\oenodeIn{})
  \psline[linecolor=DOrange, arrows=|->, arrowscale=1.5, arrowinset=0](B|A)(\oenodeCenter{})
\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
% von \Lcomp{optfilter}, \Lcomp{elecsynthesizer} und \Lcomp{optdipole} 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 by \Lcomp{optfilter}, \Lcomp{elecsynthesizer}, and \Lcomp{optdipole}.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
\psset[optexp]{labelangle=-90}
\elecsynthesizer[innercompalign=rel](0.5,1.2)(0.5,2){rel}
\elecsynthesizer[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 \Lstyle{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 \Lstyle{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)
% Linienfarbe 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 (\Lcomp{mirror} und
% \Lcomp{optgrating}).
% \fi
% \ifENGLISH The style of the arrows of variable components (\Lcomp{mirror} and
% \Lcomp{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 (\compref{lens}--\compref{polarization}), wohingegen
% z.B. Spiegel drei Knoten benötigen um korrekt ausgerichtet zu werden
% (\compref{mirror}--\compref{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 (\compref{lens}--\compref{polarization}), whereas
% e.g. mirrors require three nodes to determine the orientation
% (\compref{mirror}--\compref{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){thick lens}
  \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{Asphärische Linse}\fi
% \ifENGLISH\section{Aspheric lens}\fi
%
% \begin{ltxsyntax}
% \dipoledesc{asphericlens}
% \end{ltxsyntax}
%
% \ifGERMAN Eine asphärische Linse besitzt eine Oberfläche, deren Form durch die Gleichung
% \begin{equation*}
% z(y) = \frac{y^2}{R(1 + \sqrt{1 - (1+k)y^2/R^2})} + A_4y^4 + A_6y^6 + A_8y^8 + A_{10}y^{10}
% \end{equation*}
% gegeben ist. $z$ ist der Sagittalschnitt parallel zur optischen Achse,
% $y$ der Abstand zur optischen Achse und $R$ der
% Krümmungsradius. Desweiteren ist $k$ die konische Konstante und $A_4$,
% $A_6$, $A_8$ und $A_{10}$ die Asphärenkoeffizienten der 4. bis
% 10. Ordnung.
% \fi
% \begin{optionlist}
% \numitem[1]{asphereheight}
% \ifGERMAN Die Höhe der Linse.\fi
% \ifENGLISH The lens height.\fi
% 
% \numitem[0]{aspherewidth}
% \ifGERMAN 
% Die Breite der Linse. Wird nur verwendet, wenn der angegebene Wert
% über dem minimal berechneten liegt.
% \fi
% \ifENGLISH
% The lens center thickness. Is use only, if the given value is larger
% than the minimum calculated value.
% \fi
%
% \numitem[1]{asphereradiusleft}
% \ifGERMAN Der Krümmungsradius der linken, asphärischen Oberfläche.\fi
% \ifENGLISH Curvature radius of the left, aspheric surface.\fi
%
% \numitem[0]{asphereradiusright}
% \ifGERMAN
% Der Krümmungsradius der rechten Oberfläche. Ist dieser gleich Null,
% dann ist die Oberfläche plan.
% \fi
% \ifENGLISH
% Curvature radius of the right surface. IF the value is zero, the
% surface is plane.
% \fi
%
% \numitem{asphereconstant}
% \ifGERMAN Die konische Konstante $k$ der linken Oberfläche.\fi
% \ifENGLISH The conic constant $k$ of the left surface.\fi
%
% \optitem{aspherecoefficients}{\prm{$A_4$} [\prm{$A_6$} [\prm{$A_8$} [\prm{$A_{10}$}]]]}
% \ifGERMAN 
% Die Asphärenkoeffizienten $A_4$ bis $A_{10}$. Es können ein bis vier
% Zahlen angegeben werden.
% \fi
% \ifENGLISH
% The aspheric terms of fourth to tenth order. One to four values can be
% specified.
% \fi
% \end{optionlist}
%
% \ifGERMAN
% Als Beispiel nehmen wir die Parameter einer kommerziell erhältlichen
% asphärische
% Kondensorlinse\fnurl{http://www.thorlabs.de/thorproduct.cfm?partnumber=ACL25416U}:
% \fi
% \ifENGLISH
% As example we use the parameters of a commercially available condensor
% lens\fnurl{http://www.thorlabs.de/thorproduct.cfm?partnumber=ACL25416U}:
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(0,-0.3)(5,2.3)
  \pnodes(0,1){A}(5,1){B}
  \asphericlens[%
    plotstyle=cspline,
    asphereheight=2.54,
    aspherewidth=1.4,
    asphereradiusleft=0.8818197,
    aspherecoefficients=8.682e-3 6.376e-3 2.4073e-2 -1.719e-2,
    asphereconstant=-0.9992,
    asphereradiusright=6.99995](A)(B)
  \multido{\r=-1+0.1}{21}{%
    \drawbeam[beampos=\r, linewidth=0.3\pslinewidth](A){}(B)}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN Ein weiteres Beispiel zeigt anschaulich den Unterschied
% einer asphärischen Linsen zu einer sphärischen Linse mit gleichem
% Krümmungsradius:
% \fi
% \ifENGLISH 
% Another example illustrates the difference between an aspheric lens an
% a spheric lens with equal curvature:
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[pos=t,linerange={2-11}]
\psset{unit=0.5cm}
\begin{pspicture*}(15,8)
  \pnodes(0,4){A}(15,4){B}
  \asphericlens[asphereheight=7.5, asphereradiusleft=3.12848, 
    asphereconstant=-1.991145, aspherecoefficients=4.98e-3](A)(B)
  \multido{\r=-3.2+0.8}{9}{%
    \drawbeam[beampos=\r, linewidth=0.5\pslinewidth](A){}(B)}
  \lens[lens=3.12848 0 6 5.49, abspos=6.13, style=Refline, linestyle=dashed](A)(B)
  \multido{\r=-2.8+0.8}{8}{%
    \drawbeam[beampos=\r, linewidth=0.5\pslinewidth, linecolor=red](A){}(B)}%
\end{pspicture*}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \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{Pfeilkomponente}\fi
% \ifENGLISH\section{Arrow component}\fi
% 
% \begin{ltxsyntax}
% \dipoledesc{optarrowcomp}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.7)
  \optarrowcomp[wire](0,1)(3,1){box}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \ifENGLISH A general purpose component, similar to \Lcomp{fiberdelayline},
% but much more flexible.
% \fi
% \ifGERMAN Eine Komponente für den allgemeinen, flexiblen Gebrauch
% ähnlich zu \Lcomp{fiberdelayline}, aber deutlich variabler.
% \fi
% \end{ltxsyntax}
% 
% \begin{optionlist}
% \numitem[1.4]{arrowcompwidth}
% \ifGERMAN Die Breite der Box.\fi
% \ifENGLISH The width of the box.\fi
%
% \numitem[0.8]{arrowcompheight}
% \ifGERMAN Die Höhe der Komponente.\fi
% \ifENGLISH The height of the Komponente.\fi
%
% \optitem{arrowcompsize}{\prm{size} or \prm{width} \prm{height}}
% \ifGERMAN Die Breite und Höhe der Komponente, äquivalent zum Aufruf von
% \Lkeyword{arrowcompwidth} und \Lkeyword{arrowcompheight}.
% \fi
% \ifENGLISH The width and height of the component, is equivalent to calling both
% \Lkeyword{arrowcompwidth} and \Lkeyword{arrowcompheight}.
% \fi
%
% \numitem[70]{arrowcompangle}
% \ifGERMAN Der Winkel des Pfeils bezüglich der $x$-Achse.\fi
% \ifENGLISH The angle of the arrow with respect to the $x$-axis.\fi
%
% \choitem[rectangle]{arrowcompshape}{rectangle, circle}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]arrowcompshape}]
\begin{pspicture}(3,1)
  \optarrowcomp[arrowcompshape=circle, wire](0,0.5)(3,0.5)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
% \begin{stylelist}
% \styleitem[arrowinset=0, arrows=->]{ArrowCompStyle} 
% \ifGERMAN 
% Der Stil für den Pfeil. Das kann insbesonders nützlich sein um die
% Länge und Ausrichtung des Pfeils zu verändern.
% \fi
% \ifENGLISH 
% The style of the arrow. This can be especially useful to
% adapt the length and orientation of the arrow.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]ArrowCompStyle}]
\begin{pspicture}(3,1.5)
  \addtopsstyle{ArrowCompStyle}{xunit=-1, arrowscale=2}
  \optarrowcomp[fiber](0,1)(3,1){delay line}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{stylelist}
%
% \ifGERMAN\section{Balkenkomponente}\fi
% \ifENGLISH\section{Bar component}\fi
% 
% \begin{ltxsyntax}
% \dipoledesc{optbarcomp}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.5)
  \optbarcomp[fiber](0,1)(3,1){box}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \ifENGLISH A general purpose component, similar to \Lcomp{optfiberpolarizer},
% but much more flexible.
% \fi
% \ifGERMAN Eine Komponente für den allgemeinen, flexiblen Gebrauch
% ähnlich zu \Lcomp{optfiberpolarizer}, aber deutlich variabler.
% \fi
% \end{ltxsyntax}
% 
% \begin{optionlist}
% \numitem[1.4]{barcompwidth}
% \ifGERMAN Die Breite der Box.\fi
% \ifENGLISH The width of the box.\fi
%
% \numitem[0.8]{barcompheight}
% \ifGERMAN Die Höhe der Box.\fi
% \ifENGLISH The height of the box.\fi
%
% \optitem{barcompsize}{\prm{size} or \prm{width} \prm{height}}
% \ifGERMAN Die Breite und Höhe der Box, äquivalent zum Aufruf von
% \Lkeyword{barcompwidth} und \Lkeyword{barcompheight}.
% \fi
% \ifENGLISH The width and height of the box, is equivalent to calling both
% \Lkeyword{barcompwidth} and \Lkeyword{barcompheight}.
% \fi
%
% \numitem[70]{barcompangle}
% \ifGERMAN Der Winkel des Balkens bezüglich der $x$-Achse.\fi
% \ifENGLISH The angle of the bar with respect to the $x$-axis.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]barcompangle}]
\begin{pspicture}(3,1)
  \optbarcomp[barcompangle=90, fiber](0,0.5)(3,0.5)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \choitem[rectangle]{barcompshape}{rectangle, circle}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]barcompshape}]
\begin{pspicture}(3,1)
  \optbarcomp[barcompshape=circle, fiber](0,0.5)(3,0.5)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
% \begin{stylelist}
%   \styleitem{BarCompStyle}
%   \ifENGLISH The style of the bar.\fi
%   \ifGERMAN Der Stil für den Balken.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]BarCompStyle}]
\begin{pspicture}(3,1)
  \newpsstyle{BarCompStyle}{unit=0.7, arrows=->}
  \optbarcomp[barcompshape=circle, barcompangle=45, fiber](0,0.5)(3,0.5)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{stylelist}
%
% \ifGERMAN\section{Optische Quelle}\fi
% \ifENGLISH\section{Optical source}\fi
% 
% \begin{ltxsyntax}
% \dipoledesc{optsource}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
  \optsource(1.5,1)(3,1){Laser}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifENGLISH 
% An optical source predefines some properties of any outgoing beam, if
% it is the first component in a beam path. The definable beam
% properties are \Lkeyword{beamangle}, \Lkeyword{beamwidth},
% \Lkeyword{beamdiv} and \Lkeyword{beamalign}. The properties defined by
% the optical source cannot be overwritten by the beam properties. If a
% property wasn't explicitely defined for a source, it is taken from the
% beam properties.
%
% The default settings for the component position are
% \Lkeyword{position}\opt{=start}.
% \fi
% \ifGERMAN
% Eine optische Quelle gibt ein paar Eigenschaften für alle von ihr
% ausgehenden Strahlen vor, falls es die erste Komponente in einem
% Strahlengang ist. Die verwendbaren Eigenschaften sind
% \Lkeyword{beamangle}, \Lkeyword{beamwidth}, \Lkeyword{beamdiv} und
% \Lkeyword{beamalign}. Alle Eigenschaften, die von einer optischen
% Quelle definiert werden, können nicht später durch Strahlparameter
% überschrieben werden. Wird ein Parameter nicht explizit von der Quelle
% definiert, so werden die Parameter von dem Strahl-Stil verwendet.
%
% Die Voreinstellung für die Positionierung ist
% \Lkeyword{position}\opt{=start}.
% \fi
% \end{ltxsyntax}
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(5,2)
  \pnodes(1.5,1){A}(5,1){B}
  \optsource[innerlabel, beamdiv=10, beamangle=10](A)(B){Laser}
  \lens[lens=2 2 2](A)(B)
  \optplane(B)
  \drawwidebeam{-}
  \drawbeam[linecolor=red]{-}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \begin{optionlist}
% \numitem[1.4]{sourcewidth}
% \ifGERMAN Die Breite der Box.\fi
% \ifENGLISH The width of the box.\fi
%
% \numitem[0.8]{sourceheight}
% \ifGERMAN Die Höhe der Box.\fi
% \ifENGLISH The height of the box.\fi
%
% \optitem{sourcesize}{\prm{width} \prm{height}}
% \ifGERMAN Die Breite und Höhe der Box, äquivalent zum Aufruf von
% \Lkeyword{sourcewidth} und \Lkeyword{sourceheight}.
% \fi
% \ifENGLISH The width and height of the box, is equivalent to calling both
% \Lkeyword{sourcewidth} and \Lkeyword{sourceheight}.
% \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
% \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{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-Prisma}\fi
% \ifENGLISH\section{Glan--Thompson prism}\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)
  \pnodes(0,1){A}(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
%
% \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=0.7\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{Keil}\fi
% \ifENGLISH\section{Wedge}\fi
%
% \begin{ltxsyntax}
% \dipoledesc{optwedge}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
  \optwedge[beam](0,1)(3,1){Wedge}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
%
% \begin{optionlist}
% \numitem[0.8]{wedgeheight}
% \ifGERMAN Höhe des Keils.\fi
% \ifENGLISH The height of the wedge.\fi
%
% \numitem[10]{wedgeangleright}
% \ifGERMAN Der obere Winkel der rechten Grenzfläche bezogen auf die Vertikale.\fi
% \ifENGLISH The upper angle of the right interface with respect to a vertical line.\fi
%
% \numitem[0]{wedgeangleleft}
% \ifGERMAN Der obere Winkel der linken Grenzfläche bezogen auf die Vertikale.\fi
% \ifENGLISH The upper angle of the left interface with respect to a vertical line.\fi
%
% \optitem{wedgeangles}{\prm{left}[ \prm{right}]}
% \ifGERMAN
% Erlaubt beide Winkel gleichzeitig zu setzen. Wird nur ein Wert
% angegeben, dann wird dieser für beide Winkel verwendet.
% \fi
% \ifENGLISH
% Allows setting both angles at once. If only a single value is given,
% it is used for both angles.
% \fi
% \numitem[0]{wedgewidth}
% \ifGERMAN Ist der Wert größer als die berechnete Grundbreite, dann wird der Keil auf die angegebene Breite vergrößert.\fi
% \ifENGLISH If this value is larger than the calculated base width, then the wedge's width is increase to this value.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(2,1)
  \optwedge[wedgeangles=10 0, wedgewidth=0.4](0,0.5)(2,0.5)
  \drawwidebeam[beamwidth=0.5](0,0.5){}(2,0.5)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \end{optionlist}
%
% \ifGERMAN\section{Axikon}\fi
% \ifENGLISH\section{Axicon}\fi
%
% \begin{ltxsyntax}
% \dipoledesc{axicon}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
  \axicon[label=1](0,1)(3,1){Axicon}
  \drawwidebeam[beamwidth=0.5](0,1){}(3,1)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
%
% \begin{optionlist}
% \numitem[1.5]{axiconheight}
% \ifGERMAN Die Höhe des Axikons.\fi
% \ifENGLISH The height of the axicon.\fi
%
% \numitem[0.4]{axiconwidth}
% \ifGERMAN Die Breite des Axikons.\fi
% \ifENGLISH The width of the axicon.\fi
%
% \numitem[10]{axiconangle}
% \ifGERMAN Der obere Winkel der rechten Grenzfläche bezogen auf die Vertikale.\fi
% \ifENGLISH The upper angle of the right interface with respect to a vertical line.\fi
%
% \end{optionlist}
%
% \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{Parabolspiegel}\fi
% \ifENGLISH\section{Parabolic mirror}\fi
%
% \begin{ltxsyntax}
%   \dipoledesc{parabolicmirror}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
  \parabolicmirror(0,1)(2,1){PM}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
%
% \begin{optionlist}
%   \numitem[1]{parmirrorwidth}
%   \ifGERMAN Die Breite des Parabolspiegels.\fi
%   \ifENGLISH The width of the parabolic mirror.\fi
%
%   \numitem[1]{parmirrorheight}
%   \ifGERMAN Die Höhe des Parabolspiegels.\fi
%   \ifENGLISH The height of the parabolic mirror.\fi
% \end{optionlist}
% 
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(0,-2)(3,2)
  \parabolicmirror[parmirrorheight=4, parmirrorwidth=2](0,0)(3,0)
  \addtopsstyle{Beam}{beamalign=abs, linewidth=0.2\pslinewidth, beaminsidelast, stopinsidecount=1}
  \multido{\r=-1.55+0.1}{33}{%
    \drawbeam[beampos=\r](0,0){1}}
\end{pspicture}
\end{LTXexample}

\begin{LTXexample}
\begin{pspicture}(0,-1)(3,1)
  \optplane(0,0)
  \parabolicmirror[parmirrorheight=2, parmirrorwidth=1.5](0,0)(3,0)
  \addtopsstyle{Beam}{arrows=->, beamalign=abs}
  \drawbeam[beampos=0.5, linecolor=red]{1}{2}{1}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN\section{Off-axis-Parabolspiegel}\fi
% \ifENGLISH\section{Off-axis parabolic mirror}\fi
%
% \begin{ltxsyntax}
%   \xLtripole{oapmirror}%
%   \compitem{oapmirror}[options](in)(center)(focus){label}%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2.5)
  \oapmirror(3,2)(1,2)(2,0){OAP}
  \drawwidebeam[beamwidth=0.5](3,2){1}(2,0)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
%
% \begin{optionlist}
%   \optitem[1]{oapmirroraperture}{\prm{num} or \prm{inner} \prm{outer}}
%   \ifGERMAN 
%   Apertur des Spiegels bezogen auf die Eingangsrichtung. Wird eine
%   Zahl angegeben, dann gibt diese die gesamte Apertur an, die vertikal
%   und symmetrisch zur Verbindung zwischen \prm{in} und \prm{center}
%   gemessen wird. Bei zwei Zahlen geben diese die innere und äußere
%   Apertur an.
%   \fi
%   \ifENGLISH 
%   Mirror aperture with respect to the input direction. If a single
%   number is given, it specifies the whole aperture, measured
%   perpendicularly and symmetric to the connection from \prm{in} to
%   \prm{center}. Two numbers give the inner and the outer apertures.
% \fi
% \end{optionlist}
% 
% \ifGERMAN \newpage
% Die Konstruktion des Spiegels anhand der vorgegebenen Punkte geschieht
% wie folgt: Die Gerade von Knoten \prm{in} zu \prm{center} liegt
% parallel zur optischen Achse, \prm{focus} gibt den Fokuspunkt der
% Parabel an. Die Apertur des Spiegels wird mittels des Parameters
% \Lkeyword{oapmirroraperture} angegeben, gemessen senkrecht zum
% einfallenden Strahl.
%
% Die unterschiedlichen Parameter und die zugrundeliegende ganze Parabel
% sind in der folgenden Skizze dargestellt:
% \fi
% \ifENGLISH 
% The mirror construction using the given nodes is done as follows: the
% line from node \prm{in} to \prm{center} is parallel to the optical
% axis, \prm{focus} specifies the focal point of the parabola. The
% mirror aperture is given by the parameter
% \Lkeyword{oapmirroraperture}, measured perpendicular to the incoming
% beam.
%
% The different parameters and the whole original parabola are shown in
% the following illustration:
% \fi
%
% \iffalse
%<*ignore>
% \fi
\ifENGLISH
\begin{LTXexample}[linerange={1-2,4-6,15-15}]
\begin{pspicture}(6,5)
\pnodes(5.5,3){In}(1.5,3){Center}(1.5,1.5){Focus}
\oapmirror[oapmirroraperture=3 2, linestyle=dashed, style=Refline](In)(Center)(Focus)
\oapmirror[oapmirroraperture=1.5, linewidth=3\pslinewidth, plotpoints=200](In)(Center)(Focus){OAP}
\multido{\r=-0.5+0.5}{3}{%
  \drawbeam[beampos=\r](In){}(Focus)}
\psset{style=Refline}\color{Refline}
\psdot(In)\uput[0](In){In}\psdot(Center)\uput[180](Center){\rput[r](0,0){Center}}\psdot(Focus)\uput[-90](Focus){Focus}
\pnodes([Xnodesep=1]Center){TmpA}([Xnodesep=1,offset=0.75]Center){TmpB}
\psline[arrowscale=1.5, arrows=<->](TmpA)(TmpB)\rput[l]([Xnodesep=0.3]TmpB){outer aperture}
\pnode([Xnodesep=1,offset=-0.75]Center){TmpB}
\psline[arrowscale=1.5, arrows=<->](TmpA)(TmpB)\rput[l]([Xnodesep=0.3]TmpB){inner aperture}
\pnode(In|Focus){Tmp}
\psline[linestyle=dotted]([Xnodesep=-1.5]Focus)(Tmp)\rput[r]([offset=-0.5]Tmp){optical axis}
\end{pspicture}
\end{LTXexample}
\fi\ifGERMAN
\begin{LTXexample}[linerange={1-2,4-6,15-15}]
\begin{pspicture}(6,5)
\pnodes(5.5,3){In}(1.5,3){Center}(1.5,1.5){Focus}
\oapmirror[oapmirroraperture=3 2, linestyle=dashed, style=Refline](In)(Center)(Focus)
\oapmirror[oapmirroraperture=1.5, linewidth=3\pslinewidth, plotpoints=200](In)(Center)(Focus){OAP}
\multido{\r=-0.5+0.5}{3}{%
  \drawbeam[beampos=\r](In){}(Focus)}
\psset{style=Refline}\color{Refline}
\psdot(In)\uput[0](In){In}\psdot(Center)\uput[180](Center){\rput[r](0,0){Center}}\psdot(Focus)\uput[-90](Focus){Focus}
\pnodes([Xnodesep=1]Center){TmpA}([Xnodesep=1,offset=0.75]Center){TmpB}
\psline[arrowscale=1.5, arrows=<->](TmpA)(TmpB)\rput[l]([Xnodesep=0.3]TmpB){aeussere Apertur}
\pnode([Xnodesep=1,offset=-0.75]Center){TmpB}
\psline[arrowscale=1.5, arrows=<->](TmpA)(TmpB)\rput[l]([Xnodesep=0.3]TmpB){innere Apertur}
\pnode(In|Focus){Tmp}
\psline[linestyle=dotted]([Xnodesep=-1.5]Focus)(In|Focus)\rput[r]([offset=-0.5]Tmp){optische Achse}
\end{pspicture}
\end{LTXexample}
\fi
% \iffalse
%</ignore>
% \fi
%
%
% \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 \Lcomp{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 \Lcomp{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){G}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
%
% \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){G}
\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){G}
\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){G}
\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)
\pnodes(0.5,0){A}(0.5,1.5){B}(2,1.5){C}(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}
%
% \ifGERMAN\section{Transmissionsgitter}\fi
% \ifENGLISH\section{Transmission grating}\fi
% 
% \begin{ltxsyntax}
% \tripoledesc{transmissiongrating}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
  \transmissiongrating[beam](0,1)(1.5,1)(3,0.5){TG}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
%
% \ifGERMAN 
% Das Transmissiongitter unterstützt alle Optionen von
% \Lcomp{optgrating}. Der Strahlengang wird so berechnet, dass der
% Strahl an einer Ebene senkrecht zum dargestellten Gitter reflektiert
% wird. Diese Ebene ist im folgenden Beispiel dargestellt:
% \fi
% \ifENGLISH
% The transmission grating supports all options of
% \Lcomp{optgrating}. The beam path is calculated such, that the beam is
% reflected at an interface which is perpendicular to the drawn
% grating. This virtual interface is shown in the following example:
% \fi
%
% \hspace*{\fill}%
% \begin{pspicture}(3,3)
%  \transmissiongrating[beam, label=0 . . relative](0,1)(1.5,1)(3,0.5){\psline[linewidth=0.7\pslinewidth, linestyle=dashed](0,-1)(0,1)}
%   \ifENGLISH
%     \rput[lB](0,2.4){\parbox{3cm}{virtual reflection interface}}
%   \fi
%   \ifGERMAN
%     \rput[lB](0,2.4){\parbox{3cm}{Virtuelle \\ Reflexionsebene}}
%   \fi
% \end{pspicture}
% \hspace*{\fill}%
% \begin{pspicture}(3.5,3)
%   \pnodes(0,1.3){A}(2,1.3){B}(1,0.3){C}
%   \optgrating[reverse, gratingcount=9](A)(B)(C)
%   \optplane[angle=45](C)
%   \addtopsstyle{Beam}{ArrowInside=->, ArrowInsidePos=0.8, arrowinset=0, arrowscale=1.5}
%   \drawbeam[linecolor=black](A){1}
%   \addtopsstyle{Beam}{loadbeam, savebeam=false}
%   \drawbeam[linecolor=green]{1-2}
%   \drawbeam[linecolor=red, beamangle=15]{1-2}
%   \drawbeam[linecolor=blue, beamangle=-15]{1-2}
%   \ifENGLISH
%     \rput[lB](0,2.4){\parbox{5cm}{reflection grating\\\Lcomp{optgrating}}}
%   \fi
%   \ifGERMAN
%     \rput[lB](0,2.4){\parbox{5cm}{Reflexionsgitter\\\Lcomp{optgrating}}}
%   \fi
% \end{pspicture}
% \hspace*{\fill}%
% \begin{pspicture}(4,3)
%   \pnodes(0,1.3){A}(2,1.3){B}(4,1){C}
%   \transmissiongrating[reverse, gratingcount=9](A)(B)(C)
%   \optplane[angle=-30](C)
%   \addtopsstyle{Beam}{ArrowInside=->, ArrowInsidePos=0.8, arrowinset=0, arrowscale=1.5}
%   \drawbeam[linecolor=black](A){1}
%   \addtopsstyle{Beam}{loadbeam, savebeam=false}
%   \drawbeam[linecolor=green]{1-2}
%   \drawbeam[linecolor=red, beamangle=5]{1-2}
%   \drawbeam[linecolor=blue, beamangle=-5]{1-2}
%   \ifENGLISH
%     \rput[lB](0,2.4){\parbox{5cm}{transmission grating\\\Lcomp{transmissiongrating}}}
%   \fi
%   \ifGERMAN
%     \rput[lB](0,2.4){\parbox{5cm}{Transmissionsgitter\\\Lcomp{transmissiongrating}}}
%   \fi
% \end{pspicture}
% \hspace*{\fill}%
% 
% \ifENGLISH If this is not what you want, you may e.g. rotate the
% component further with \Lkeyword{angle}, and then adjust also the
% \Lkeyword{beamangle}.
% \fi 
% \ifGERMAN Ist dieses Verhalten nicht gewünscht, so kann man z.B. die
% Komponente mit \Lkeyword{angle} weiter drehen, und den Strahlwinkel
% mit \Lkeyword{beamangle} entsprechend korrigieren.
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.4)
  \pnodes(0,1){A}(1,1){B}(3,0.6){C}
  \transmissiongrating[angle=-10, reverse](A)(B)(C){TG}
  \addtopsstyle{Beam}{ArrowInside=->, ArrowInsidePos=0.8, arrowinset=0, arrowscale=1.5}
  \drawbeam[linecolor=black](A){1}
  \drawbeam[linecolor=green, loadbeam, beamangle=20]{1}(C)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN\section{Akustooptischer Modulator}\fi
% \ifENGLISH\section{Acousto-optic modulator}\fi
%
% \begin{ltxsyntax}
%   \xLtripole{optaom}\compitem{optaom}[options](in)(trans)(diff){label}
% \end{ltxsyntax}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-3,7-7}]
\begin{pspicture}(3,2)
  \pnodes(0,1.5){A}(3,0.5){B}(3,1.5){C}
  \optaom[beam](A)(B)(C){AOM}
  \psdots(A)(B)(C)
  \color{Refline}
  \uput[-90](A){A}\uput[-90](B){B}\uput[-90](C){C}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN 
% Dieses Makro stellt einen akustooptischen Modulator dar. Dieser kann,
% ähnlich einem \Lcomp{beamsplitter} entweder transmittierend oder
% reflektierend sein. Beachten Sie, dass die Knoten nicht so angeordnet
% sind, wie bei den üblichen Tripolen wie z. B. dem
% \Lcomp{optgrating}. Der mittlere Knoten gibt die Richtung eines
% transmittierten, und der dritte Knoten die Richtung der ersten
% Beugungsordnung an.
%
% Diese erste Umsetzung des AOM in Version 4.8 ist
% noch etwas experimentell, da ich nicht genügend Testfälle hatte um
% alle Eventualitäten zu prüfen. Es könnten sich also noch Änderungen
% ergeben, die nicht abwärts kompatibel sind. 
% \fi
% \ifENGLISH
% This macro draw an acousto-optic modulator, which either be
% transmittive or reflective, like a \Lcomp{beamsplitter}. Please note,
% that the nodes do not correspond to those of a usual tripole like an
% \Lcomp{optgrating}. The second node is in the direction of the
% transmitted beam, the third node gives the direction of the first
% diffraction order.
%
% This first implementation in version 4.8 is still experimental,
% because I didn't have enough test cases to check all possible
% cases. Therefore, future versions may have changes, which are not
% backwards compatible.
% \fi
%
% \begin{optionlist}
% \numitem[1]{aomheight}
% \ifGERMAN Die Höhe des Modulators.\fi
% \ifENGLISH The height of the modulator.\fi
%
% \numitem[1.5]{aomwidth}
% \ifGERMAN Die Breite des Modulators.\fi
% \ifENGLISH The width of the modulator.\fi
%
% \optitem{aomsize}{\prm{width} \prm{height}}
% \ifGERMAN Die Breite und Höhe des Modulators, äquivalent zum Aufruf von
% \Lkeyword{aomwidth} und \Lkeyword{aomheight}.
% \fi
% \ifENGLISH The width and height of the modulator, is equivalent to calling both
% \Lkeyword{aomwidth} and \Lkeyword{aomheight}.
% \fi
%
% \intitem[9]{aomgratingcount}
% \ifGERMAN 
% Gibt die Anzahl der Gitterlinien an. Werden weitere Änderungen des
% Gitters oder des Modulators allgemein gewünscht, dann muss der Parameter
% \Lkeyword{aomcomp} verwendet werden.
% \fi
% \ifENGLISH 
% Changes the number of grating lines. For other changes of the grating
% you must use the \Lkeyword{aomcomp} parameter to redefine the whole grating.
% \fi
%
% \choitem[symmetric]{aomalign}{symmetric, straight}
% \ifGERMAN 
% Die Ausrichtung eines \Lcomp{optaom} bezüglich der drei Referenzknoten
% kann mit diesem Parameter eingestellt werden. Die symmetrische
% (\opt{symmetric}) Ausrichtung ist im folgenden Beispiel zu sehen:
% \fi
% \ifENGLISH 
% The alignment of an \Lcomp{optaom} with respect to the three reference
% nodes can be set with this option. The \opt{symmetric} alignment is
% shown in the following example:
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-6,11-11}]
\begin{pspicture}(3,2)
  \pnodes(0,1.5){A}(3,0.5){B}(3,1.5){C}
  \optaom[aomalign=symmetric](A)(B)(C){symmetric}
  \addtopsstyle{Beam}{fillstyle=solid, linestyle=none, beamwidth=0.1}
  \drawwidebeam[fillcolor=red!50](A){}(C)
  \drawwidebeam[fillcolor=red](A){}(B)
  \color{Refline}
  \psdot(A)\uput[-90](A){A}
  \psdot(B)\uput[-90](B){B}
  \psdot(C)\uput[90](C){C}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN
% In der geraden (\opt{straight}) Ausrichtung sieht der Strahlengang wie
% folgt aus:
% \fi
% \ifENGLISH
% For \opt{straight} alignment the sketch looks like
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-6,11-11}]
\begin{pspicture}(3,2)
  \pnodes(0,1){A}(3,1){B}(3,1.5){C}
  \optaom[aomalign=straight](A)(B)(C){straight}
  \addtopsstyle{Beam}{fillstyle=solid, linestyle=none, beamwidth=0.1}
  \drawwidebeam[fillcolor=red!50](A){}(C)
  \drawwidebeam[fillcolor=red](A){}(B)
  \color{Refline}
  \psdot(A)\uput[-90](A){A}
  \psdot(B)\uput[-90](B){B}
  \psdot(C)\uput[90](C){C}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \choitem[parallel]{aomreflalign}{perp, parallel}
% \ifGERMAN 
% Die Ausrichtung der reflektiven Grenzfläche kann entweder
% \opt{parallel} oder senkrecht (\opt{perp}) zur Komponente
% liegen. Diese Option ist lediglich aus technischer Sicht notwendig,
% die Richtung des reflektierten Strahls wird dadurch nicht
% verändert.
% \fi
% \ifENGLISH 
% The reflective interface can be oriented either \opt{parallel} or
% \opt{perp}endicular to the component. This option was necessary in
% first place for technical reasons, the direction of the reflected ray
% is not affected by this option.
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-5,10-10}]
\begin{pspicture}(3,2)
  \pnodes(0,1.5){A}(3,0.5){B}(3,1.5){C}
  \optaom[aomreflalign=parallel](A)(B)(C){parallel}
  \addtopsstyle{Beam}{fillstyle=solid, linestyle=none, beamwidth=0.2}
  \drawwidebeam[fillcolor=red!50](A){}(C)
  \color{Refline}
  \psdot(A)\uput[-90](A){A}
  \psdot(B)\uput[-90](B){B}
  \psdot(C)\uput[90](C){C}
\end{pspicture}
\end{LTXexample}

\begin{LTXexample}[linerange={1-5,10-10}]
\begin{pspicture}(3,2)
  \pnodes(0,1.5){A}(3,0.5){B}(3,1.5){C}
  \optaom[aomreflalign=perp](A)(B)(C){perp}
  \addtopsstyle{Beam}{fillstyle=solid, linestyle=none, beamwidth=0.2}
  \drawwidebeam[fillcolor=red!50](A){}(C)
  \color{Refline}
  \psdot(A)\uput[-90](A){A}
  \psdot(B)\uput[-90](B){B}
  \psdot(C)\uput[90](C){C}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN
% Das folgende Beispiel zeigt einen Fall, der mit
% \Lkeyword{aomreflalign}\opt{=parallel} nicht funktioniert, da der
% Einfallswinkel so flach ist, dass die Schnittpunkte mit der
% reflektierenden Grenzfläche außerhalb der Komponente liegen:
% \fi
% \ifENGLISH
% The following example show a use case, which doesn't work properly
% with \Lkeyword{aomreflalign}\opt{=parallel}, because the incident
% angle is so shallow, that the intersection points with the interface
% lay outside of the component.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.5)
  \pnodes(0,1.1){A}(3,0.8){B}(3,1.1){C}
  \optaom[aomreflalign=parallel](A)(B)(C){parallel}
  \addtopsstyle{Beam}{fillstyle=solid, linestyle=none, beamwidth=0.2}
  \drawwidebeam[fillcolor=red!50](A){}(C)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \choitem[default]{aomcomp}{default, \prm{macro}}
% \ifGERMAN Tauscht die Gitterlinien durch eine beliebige Zeichung aus.\fi
% \ifENGLISH Changes the grating lines to an arbitrary drawing.\fi
%
% \intitem[2]{diffractionorders}
% \ifGERMAN 
% Die Anzahl der Beugungsordnungen (positive und negative), die mit
% \Lkeyword{beamdiffractionorder} ausgewählt werden können, also
% $-$\prm{num},$-$\prm{num}$+1$,\ldots ,\prm{num}.
%
% Gleichzeitig werden entsprechende Knoten
% \lstinline!\oenode{DO-1}{<comp>}!, \lstinline!\oenode{DO0}{<comp>}!,
% \lstinline!\oenode{DO1}{<comp>}! usw. definiert.
% \fi
% \ifENGLISH
% The number or diffraction orders (positive and negative) which can be
% selected with \Lkeyword{beamdiffractionorder},
% i.e. $-$\prm{num},$-$\prm{num}$+1$,\ldots ,\prm{num}.
%
% At the same time the nodes \lstinline!\oenode{DO-1}{<comp>}!,
% \lstinline!\oenode{DO0}{<comp>}!, \lstinline!\oenode{DO1}{<comp>}!
% etc. are defined.
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(0,0.6)(4.3,3.6)
  \pnodes(0,2.5){A}(4,2){B}(4,2.5){C}
  \optaom[aomsize=1 2, aomreflalign=perp, diffractionorders=3](A)(B)(C)
  \addtopsstyle{Beam}{beamwidth=0.2, linestyle=none, fillstyle=solid}
  \drawwidebeam[fillcolor=red!40](A){}(C)
  \drawwidebeam[fillcolor=red](A){}(B)
  \multido{\i=-3+1}{7}{%
    \psdot(\oenode{DO\i}{})\uput[0](\oenode{DO\i}{}){\i}}%
\end{pspicture}%
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \intitem[\{\}]{beamdiffractionorder}
% \ifGERMAN
% Die Beugungsordnung, die für einen reflektierten Strahl durch den AOM
% verwendet wird. Wenn der Wert leer ist, \opt{\{\}} dann wird die
% Option ignoriert.
%
% Mit Verwendung dieser Option wird unmittelbar das Verhalten der
% Grenzfläche festgelegt, hängt also nicht von der relativen Position
% von AOM und der folgenden Komponente ab. Für
% \Lkeyword{beamdiffractionorder}$\neq 0$ wird der Strahl reflektiert,
% für den Wert $0$ hingegen transmittiert. Der Parameter
% \Lkeyword{beammode} wird dann ignoriert.
%
% Es können nur die Beugungsordnungen verwendet werden, die für die
% entsprechende Komponente mit \Lkeyword{diffractionorders} definiert
% wurden. Wird eine nicht-definierte Ordnung verwendet, dann wird die
% nächstliegende verwendet und eine Postscript-Warnung (siehe
% \Lkeyword{pswarning}) ausgegeben.
% \fi
% \ifENGLISH
% The diffraction order, which is used for a reflected beam going
% through the aom. The option is ignored if its value is empty
% \opt{\{\}}.
%
% By using this option you automatically select the behaviour of the
% interface, which then doesn't depend on the relative position of AOM
% and the following component. For \Lkeyword{beamdiffractionorder}$\neq
% 0$ a beam gets reflected, for the value $0$ it gets transmitted. The
% parameter \Lkeyword{beammode} is ignored.
%
% You can select only those orders, where have been defined for the
% respective component with \Lkeyword{diffractionorders}. If an
% undefined order is selected, the closest one is choosen instead and a
% Postscript warning is issued (see \Lkeyword{pswarning}).
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[pos=t, linerange={1-7,12-12}]
\begin{pspicture}(0,-0.2)(4.4,3.8)
  \pnodes(0,2.5){A}(4,2){B}(4,2.5){C}
  \optaom[aomsize=1 2, aomreflalign=perp, diffractionorders=3](A)(B)(C)
  \optplane(B)
  \addtopsstyle{Beam}{beamwidth=0.2, linestyle=none, fillstyle=solid}
  \multido{\i=-3+1,\r=10+15}{7}{%
    \drawwidebeam[fillcolor=red!\r, beamdiffractionorder=\i](A){-}}
  \color{Refline}
  \uput[90](A){A}\psdot(A)
  \uput[0](B){B}\psdot(B)
  \uput[0](C){C}\psdot(C)
\end{pspicture}%
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
%
% \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[transmittive]{prismtype}{transmittive, reflective}
% \ifGERMAN Ist dieser Parameter auf \opt{reflective} gesetzt, so wird
% die Grundfläche als zusätzliche, reflektierende Grenzfläche
% verwendet.
% \fi
% \ifENGLISH If this parameter is set to \opt{reflective}, the prism
% base is used as additional, reflective interface.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]prismtype}]
\begin{pspicture}(1.5,0.6)(5.1,2.2)
  \optprism[prismtype=reflective](0,1)(3,0.9)(6,1)
  \lens(1,2)(\oenodeIfc{2}{1})
  \lens(\oenodeIfc{2}{1})(5,2)
  \drawwidebeam[beamwidth=0.3, fillstyle=solid, fillcolor=green, opacity=0.3](1,2){2}{1}{3}(5,2)
\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}(0,-0.5)(14,3.2)
  \footnotesize
  \pnodes(0,1){A}(2,2){B}(4,1){C}
  \psdot(A)\uput[90](A){A}
  \psdot(B)\uput[90](B){B}
  \psdot(C)\uput[90](C){C}
  \optprism[prismsize=2](A)(B)(C)
  \psline[style=Refline, linestyle=dashed](A)(B)(C)
  \newpsstyle{IfcDot}{dotstyle=+, linecolor=red, linewidth=1.5\pslinewidth}
  \psdot[style=IfcDot](\oenodeCenter{})\uput{0.1}[-90](\oenodeCenter{}){\prm{center}}
  \psdot[style=IfcDot](\oenodeIn{})\uput{0.1}[150](\oenodeIn{}){\prm{in}}
  \psdot[style=IfcDot](\oenodeOut{})\uput{0.1}[30](\oenodeOut{}){\prm{out}}
  \rput[t](\oenodeCenter{}|0,0.2){%
    \begin{tabular}{@{}c@{}}\opt{prismalign=auto}\\\opt{prismtype=transmittive}\end{tabular}}

  \pnodes(5,1){A}(7,2){B}(9,1){C}
  \psdot(A)\uput[90](A){A}
  \psdot(B)\uput[90](B){B}
  \psdot(C)\uput[90](C){C}
  \optprism[prismsize=2, prismalign=center](A)(B)(C)
  \psline[style=Refline, linestyle=dashed](A)(B)(C)
  \newpsstyle{IfcDot}{dotstyle=+, linecolor=red, linewidth=1.5\pslinewidth}
  \psdot[style=IfcDot](\oenodeCenter{})\uput{0.1}[-90](\oenodeCenter{}){\prm{center}}
  \psdot[style=IfcDot](\oenodeIn{})\uput{0.1}[150](\oenodeIn{}){\prm{in}}
  \psdot[style=IfcDot](\oenodeOut{})\uput{0.1}[30](\oenodeOut{}){\prm{out}}
  \rput[t](\oenodeCenter{}|0,0.2){%
    \begin{tabular}{@{}c@{}}\opt{prismalign=center}\\\opt{prismtype=transmittive}\end{tabular}}

  \pnodes(10,2){A}(12,1){B}(14,2){C}
  \psdot(A)\uput[90](A){A}
  \psdot(B)\uput[-90](B){B}
  \psdot(C)\uput[90](C){C}
  \optprism[prismsize=2, prismtype=reflective](A)(B)(C)
  \psline[style=Refline, linestyle=dashed](A)(B)(C)
  \newpsstyle{IfcDot}{dotstyle=+, linecolor=red, linewidth=1.5\pslinewidth}
  \psdot[style=IfcDot](\oenodeCenter{})\uput{0.1}[90](\oenodeCenter{}){\prm{center}}
  \psdot[style=IfcDot](\oenodeIn{})\uput{0.1}[-160](\oenodeIn{}){\prm{in}}
  \psdot[style=IfcDot](\oenodeOut{})\uput{0.1}[-20](\oenodeOut{}){\prm{out}}
  \rput[t](\oenodeCenter{}|0,0.2){%
    \begin{tabular}{@{}c@{}}\opt{prismalign=auto}\\\opt{prismtype=reflective}\end{tabular}}
\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)
  \pnodes(0,2){A}(2.5,0.5){G}(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
%
% \choitem[auto]{raprismalign}{auto, center}
% \ifGERMAN Schaltet die automatische Positionierung der Komponente
% vertikal zur Eingangsfläche ein oder aus:
% \fi
% \ifENGLISH Switch between automatic and fixed alignment of the
% component vertical to the entrance interface:
% \fi
%
% \begin{pspicture}(0,-0.5)(13,2)
%   \pnodes(0,1.6){A}(0,0.4){B}
%   \rightangleprism(A)(2,1)(B)\psdot(\oenodeCenter{})
%   \drawbeam(A){}(B)
%   \pnodes(3,1.2){A}(3,0.8){B}
%   \rightangleprism(A)(5,1)(B)\psdot(\oenodeCenter{})
%   \drawbeam(A){}(B)
%   \rput[t](3,0){\opt{raprismalign=auto}}
%   \psset{raprismalign=center}
%   \pnodes(7,1.6){A}(7,0.4){B}
%   \rightangleprism(A)(9,1)(B)\psdot(\oenodeCenter{})
%   \drawbeam(A){}(B)
%   \pnodes(10,1.2){A}(10,0.8){B}
%   \rightangleprism(A)(12,1)(B)\psdot(\oenodeCenter{})
%   \drawbeam(A){}(B)
%   \rput[t](10,0){\opt{raprismalign=center}}
% \end{pspicture}
%
% \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 (\compref{optcirculator})
% werden anders ausgerichtet.
% \fi
%
% \begin{optionlist}
%   \boolitem{usefiberstyle} 
%   \ifGERMAN
%   Bei manchen Komponenten (z.B. \Lcomp{optfilter} oder \Lcomp{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. Hat Vorrang vor der Option
%   \Lkeyword{usewirestyle}, sind beide Optionen gesetzt, dann wird eine
%   Faser gezeichnet.
%   \fi
%   \ifENGLISH
%   For some components (e.g. \Lcomp{optfilter} or \Lcomp{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. Takes precedence over
%   \Lkeyword{usewirestyle}.
%   \fi
%   \boolitem{usewirestyle} 
%   \ifGERMAN
%   Kann verwendet werden, um interne Verbindungen als \Lstyle{Wire}
%   darzustellen. Setzt \Lkeyword{usefiberstyle} auf \opt{false}, daher
%   kann es sinnvoll sein, z.B. einen elektrischen Filter zu definieren:
%   \fi
%   \ifENGLISH
%   Can be used to draw internal connections als \Lstyle{Wire}. Sets
%   \Lkeyword{usefiberstyle} to \opt{false}, therefore it can be useful
%   to define e.g. an electrical filter:
%   \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{lstlisting}
\newpsobject{elecfilter}{optfilter}{usewirestyle}
\end{lstlisting}
% \iffalse
%</ignore>
% \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.2]{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 
% Siehe \Lstyle{ArrowCompStyle}.
% \fi
% \ifENGLISH 
% See \Lstyle{ArrowCompStyle}.
% \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}%
% \compitem{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}%
% \compitem{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}%
% \compitem{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}%
% \compitem{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.05]{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
%
% \ifENGLISH If this value is set to \{\}, the separation is calculated
% automatically according to the \Lkeyword{couplertype} and
% \Lkeyword{couplersize}.
% \fi
% \ifGERMAN Wird dieser Wert auf \{\} gesetzt, dann wird der Abstand
% automatisch berechnet, abhängig von \Lkeyword{couplertype} und
% \Lkeyword{couplersize}.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{couplersep}}]
\begin{pspicture}(3,4.5)
  \psset{couplersep={}, couplersize=0.5, 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=ellipse]%
       (0,1.5)(0,0.5)(3,1.5)(3,0.5){ellipse}
\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
%
% \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\subsection{Variable Knotenanzahl}\fi
% \ifENGLISH\subsection{Variable node count}\fi
% \ifGERMAN
% Jeder Koppler hat eine Variante, die nur zwei Knoten benötigt, einen Eingangs-
% und einen Ausgangsknoten. \Lcomp{optcoupler} verwendet jeden dieser Knoten
% zweimal, \Lcomp{wdmsplitter} verwendet den Knoten \prm{out} zweimal und
% \Lcomp{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 \Lcomp{optcoupler}, both nodes are used twice,
% \Lcomp{wdmsplitter} uses node \prm{out} twice, and \Lcomp{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)
  \pnodes(0,1){A}(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 Des Weiteren kann ein \Lcomp{wdmcoupler} mehr als zwei Eingangsknoten haben, ein
% \Lcomp{wdmsplitter} mehr als zwei Ausgangsknoten.\fi
% \ifENGLISH A \Lcomp{wdmcoupler} can have more than two input nodes, a \Lcomp{wdmsplitter}
% more than two output nodes.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(4,2)
  \pnodes(0,2){A}(0,1.2){B}(0,0.8){C}(0,0){D}(4,1){E}
  \wdmcoupler(A)(B)(C)(D)(E){coupler}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(4,2)
  \pnodes(0,1){A}(4,2){B}(4,1.2){C}(4,0.8){D}(4,0){E}
  \wdmsplitter(A)(B)(C)(D)(E){splitter}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN Die Ausrichtung der Komponente wird anhand des Mittelpunkts aller Eingangs-
% (\Lcomp{wdmcoupler}) bzw. Ausgangsknoten (\Lcomp{wdmsplitter})
% berechnet, falls nicht \Lkeyword{coupleralign} verwendet wird.\fi
% \ifENGLISH The component's orientation is calculated from the median of all input nodes
% (\Lcomp{wdmcoupler}) or all output nodes (\Lcomp{wdmsplitter}), unless \Lkeyword{coupleralign}
% is used.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(4,2)
  \pnodes(0,2){A}(0,0.5){B}(0,0){C}(4,1){D}
  \wdmcoupler(A)(B)(C)(D){coupler}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(4,2)
  \pnodes(0,2){E}(0,0.5){F}(0,0){G}(4,2){H}
  \wdmcoupler[coupleralign=t](E)(F)(G)(H){coupler}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(4,2)
  \pnodes(0,1){A}(4,2){B}(4,0.5){C}(4,0){D}
  \wdmsplitter(A)(B)(C)(D){splitter}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(4,2)
  \pnodes(0,0.5){E}(4,2){F}(4,1.5){G}(4,0){H}
  \wdmsplitter[coupleralign=b](E)(F)(G)(H){splitter}
\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.6, couplertype=rectangle, couplersep=0.25}
% \wdmsplitter(0,1.25)(3,2)(3,1.25)(3,0.5)
% \psdot(\oenodeIfc{1}{})\uput[120](\oenodeIfc{1}{}){1}
% \psdot(\oenodeIfc{2}{})\uput[90](\oenodeIfc{2}{}){2}
% \psdot(\oenodeIfc{3}{})\uput[180](\oenodeIfc{3}{}){3}
% \psdot(\oenodeIfc{N}{})\uput[-90](\oenodeIfc{N}{}){N}
% \wdmcoupler(4,2)(4,1.25)(4,0.5)(7,1.25)
% \psdot(\oenodeIfc{1}{})\uput[90](\oenodeIfc{1}{}){1}
% \psdot(\oenodeIfc{2}{})\uput[0](\oenodeIfc{2}{}){2}
% \psdot(\oenodeIfc{3}{})\uput[-90](\oenodeIfc{3}{}){3}
% \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){\nxLcomp{wdmsplitter}}
% \rput[b](5.5,0){\nxLcomp{wdmcoupler}}
% \rput[b](9.5,0){\nxLcomp{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}%
% \compitem{fiberbox}(in)(out){label}
% \compitem*{fiberbox}(tl)(bl)(tr)(br){label}
% \end{ltxsyntax}
% 
% \ifGERMAN 
% Eine \Lcomp{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 \Lcomp{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 \Lcomp{fiberbox}
% äquivalent zu einer \Lcomp{optbox}.
% \fi
% \ifENGLISH For certain parameter configurations a \Lcomp{fiberbox} is
% equivalent to an \Lcomp{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{Elektrische Komponenten}\fi
% \ifENGLISH\chapter{Electrical components}\fi
% \label{chap:electrcomp}
%
% \ifGERMAN\section{Koppler}\fi
% \ifENGLISH\section{Coupler}\fi
%
% \begin{ltxsyntax}
% \xLemultipole{eleccoupler}%
% \compitem{eleccoupler}(tl)(bl)(tr)(br){label}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.5)
  \eleccoupler(0,1.5)(0,0)(3,1.5)(3,0)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% \begin{optionlist}
%   \optitem[0.8]{eleccouplersize}{\prm{size} or \prm{width} \prm{height}}
%   \ifGERMAN Die Breite und Höhe des Kopplers, wird nur ein Wert
%   angegeben dann ist die Komponente quadratisch.
%   \fi
%   \ifENGLISH The width and height of the couplers, if only one value
%   is given the component is squared.
%   \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]eleccouplersize}]
\begin{pspicture}(3,1.5)
  \eleccoupler[eleccouplersize=1 0.6](0,1.5)(0,0)(3,1.5)(3,0)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%   \numitem[\{\}]{eleccouplersep}
%   \ifGERMAN Der vertikale Abstand zwischen den beiden Eingangs-
%   bzw. Ausgangsanschlüssen. Ist der Wert leer, bzw. gleich \{\}, dann
%   wird der Abstand auf 75\% der Höhe gesetzt.
%   \fi
%   \ifENGLISH The vertical distance between the two input and output
%   ports. If the value is empty \{\}, then the separation is set to
%   75\% of the height.
%   \fi
%
%   \choitem[standard]{eleccouplertype}{standard, directional}
%   \ifGERMAN Wählt zwischen unterschiedlichen Kopplertypen.\fi
%   \ifENGLISH Select between different coupler types.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]eleccouplertype}]
\begin{pspicture}(3,1.5)
  \eleccoupler[eleccouplertype=directional](0,1.5)(0,0)(3,1.5)(3,0)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
%   \choitem[left]{eleccouplerinput}{left, right}
%   \ifGERMAN Gibt beim direktionalen Koppler die Eingangsseite an.\fi
%   \ifENGLISH Selects the input side for the directional coupler.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]eleccouplerinput}]
\begin{pspicture}(3,1.5)
  \eleccoupler[eleccouplertype=directional, eleccouplerinput=right](0,1.5)(0,0)(3,1.5)(3,0)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
%
% \ifGERMAN Die automatischen Verbindungen des elektrischen Kopplers
% sind, anders als beim optischen Koppler, alle auf die Komponente
% gerichtet. Das ergibt ein symmetrisches Layout der automatischen
% Verbindungen des elektrischen Kopplers bei Verwendung der Vorgabe
% \Lkeyword{wirestyle}\opt{=angle}.
% \fi
% \ifENGLISH The automatic connections of the electrical coupler are all
% directed towards the component, in contrast to the optical
% coupler. This gives a symmetric layout of the automatic electrical coupler
% connections when using the default of
% \Lkeyword{wirestyle}\opt{=angle}.
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,4)
  \addtopsstyle{Wire}{arrows=->}
  \addtopsstyle{Fiber}{arrows=->, fiberstyle=angle}
  \eleccoupler(0,4)(0,2)(3,4)(3,2)
  \optcoupler[couplersize=0.8 0.8, couplersep={}, couplertype=rectangle](0,1.5)(0,0)(3,1.5)(3,0)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN\section{Synthesizer}\fi
% \ifENGLISH\section{Synthesizer}\fi
%
% \begin{ltxsyntax}
% \xLemultipole{elecsynthesizer}%
% \compitem{elecsynthesizer}(in)(out){label}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.5)
  \elecsynthesizer(1,1)(3,1){SYN}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.5)
  \elecsynthesizer[position=0.5](0,1)(3,1){SYN}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \begin{optionlist}
%   \optitem[0.8]{synthsize}{\prm{size} or \prm{width} \prm{height}}
%   \ifGERMAN Die Größe der Komponente, ist diese rund und wurden zwei
%   Werte angegeben, dann wird der kleinere als Durchmesser verwendet.
%   \fi
%   \ifENGLISH The size of the component, if this is of circular shape
%   and two values were given, the smaller one is used as diameter.
%   \fi
%
%   \choitem[sine]{synthtype}{sine, pulse, sawtooth, rectangle, triangle, custom}
%   \ifGERMAN Wählt zwischen unterschiedlichen Typen.\fi
%   \ifENGLISH Select between different synthesizer types.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]synthtype}]
\begin{pspicture}(0,0.6)(3,5.4)
  \elecsynthesizer[synthtype=sine](1,5)(3,5)
  \elecsynthesizer[synthtype=sawtooth](1,4)(3,4)
  \elecsynthesizer[synthtype=triangle](1,3)(3,3)
  \elecsynthesizer[synthtype=rectangle](1,2)(3,2)
  \elecsynthesizer[synthtype=pulse](1,1)(3,1)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \ifGERMAN Es kann auch eine frei wählbare Wellenform gewählt werden.\fi
% \ifENGLISH You can also use a freely customizable waveform.\fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]synthtype}]
\begin{pspicture}(0,0)(3,2)
  \makeatletter
  \def\elecsynthesizer@custom{%
    \psline(-0.25,-0.1)(-0.1,-0.1)(-0.1,0)%
           (0.1,0)(0.1,0.1)(0.25,0.1)}
  \makeatother
  \elecsynthesizer[synthtype=custom](1,1)(3,1)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \choitem[circle]{synthshape}{circle, rectangle}
% \ifGERMAN Wählt zwischen kreisförmiger und rechteckiger Außenform.\fi
% \ifENGLISH Select between circular and rectangular outer shape.\fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]synthshape}]
\begin{pspicture}(3,1.5)
  \elecsynthesizer[synthshape=rectangle](1,1)(3,1){SYN}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
%
% \begin{stylelist}
% \styleitem{SynthStyle}
% \ifGERMAN Beinflusst das Aussehen der internen Symbole.\fi
% \ifENGLISH Change the style of the internal synthesizer symbol.\fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]SynthStyle}]
\begin{pspicture}(3,1)
  \newpsstyle{SynthStyle}{xunit=0.5, yunit=-1}
  \elecsynthesizer(1,0.5)(3,0.5)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{stylelist}
%
% \ifGERMAN\section{Mixer}\fi
% \ifENGLISH\section{Mixer}\fi
%
% \begin{ltxsyntax}
% \xLemultipole{elecmixer}%
% \compitem{elecmixer}(left)(right)(bottom){label}%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
  \newpsstyle{Wire}{arrowscale=1.5, arrowinset=0, arrows=->}
  \addtopsstyle{WireOut1}{linecolor=blue}
  \addtopsstyle{WireOut2}{linecolor=green!80!black}
  \elecmixer(0,1)(3,1)(1.5,0){Mixer}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{ltxsyntax}
%
% \begin{optionlist}
%   \numitem[0.8]{elecmixersize}
%   \ifGERMAN Der Durchmesser des Mixers.\fi
%   \ifENGLISH The diameter of the mixer.\fi
% \end{optionlist}
%
% \ifGERMAN Weitere Details bezüglich der Referenzknoten und
% Positionierung finden Sie unter \Lcomp{optcirculator}.
% \fi
% \ifENGLISH For further details about the reference nodes and the
% positioning, please refer to \Lcomp{optcirculator}.
% \fi
%
% \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 \Lcomp{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
% \Lcomp{fibercollimator} has one interface only, the other connection is
% a fiber and the \Lcomp{optdetector} has one interface, the other
% connection is a wire.
% \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 \Lcomp{optfilter} wird mit den Voreinstellungen zwar als
% Faserkomponente gehandhabt, kann jedoch im Gegensatz zu den reinen
% Faserkomponenten (\prettyref{chap:fibercomp}) auch als
% Freistrahlkomponente verwendet werden. Der \Lcomp{fibercollimator} hat
% nur eine Faser, die andere Verbindung ist Freistrahl und der
% \Lcomp{optdetector} hat eine Freistrahl- und eine elektrische
% Verbindung.
% \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. Anstattdessn 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}\compitem{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\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 placed by default at the end of the
% reference line (\Lkeyword{position}\opt{=end}). If this setting is
% overwritten, the output connection is treated like that of an
% electrical component.
% \fi
% \ifGERMAN Der Detektor wird in der Voreinstellung ans Ende der
% Referenzlinie platziert (\Lkeyword{position}\opt{=end}). Wird dieser
% Parameter überschrieben, dann wird die ausgehende Verbindung wie bei
% einer elektrischen Komponente behandelt.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.2)
  \optdetector[position=0.5](0,0)(1.5,1){detector}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \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=3\pslinewidth}
  \newpsstyle{DetectorStyle}{linewidth=0.333\pslinewidth}
  \optdetector[dettype=diode](0,1)(2,1)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{stylelist}
% 
%
% \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}
%   \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.
%
% IDs können auch relativ zur aktuellen ID über die Syntax
% \opt{<}\prm{num} angegeben werden: \opt{<1} ist die vorletzte ID,
% \opt{<2} die vorvorletzte ID usw. Die vorletzte ID kann abgekürzt auch
% mit \opt{<} erhalten werden, und die aktuelle ID mit \opt{<0}, was
% äquivalent zu einem leeren Parameter ist.
% \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). 
%
% ID specifications relative to the current ID can be used with the
% syntax \opt{<}\prm{num}: \opt{<1} is the previous ID, \opt{<2} is the
% current ID minus two etc. The previous ID can also be accessed by only
% \opt{<}, and the current ID is \opt{<0}, which is equivalent to an
% empty parameter.
% \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 locally, i.e. in the optional argument of a
%   \nxLPack{pst-optexp} component, and should be unique within one
%   \Lenv*{pspicture} environment.
%   \fi
% \end{optionlist}
%
% \ifGERMAN Beispiele für unterschiedliche Methoden auf ein und
% dieselbe Komponente zuzugreifen.
% \fi
% \ifENGLISH Examples for different methods to access the same
% component.
% \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
% \iffalse
%</ignore>
% \fi
% 
% \ifGERMAN 
% Die Verwendung von relativen IDs ist u.a. nützlich, um eine neue
% Komponente relativ zur vorangegangenen zu definieren. Die Verwendung
% von z.B. \Lcs{oenodeOut}\opt{\{\}} in den Referenzknoten ist nicht
% möglich, da hiermit zum Zeitpunkt der Auswertung der Koordinaten schon
% auf die neue, nicht fertige Komponente referenziert wird. Ein Aufruf
% der Art \lstinline!\optbox(\oenodeOut{})(B)! ist daher nicht möglich,
% und führt zu einem Fehler. Mit relativen IDs kann das allerdings mit
% \lstinline!\optbox(\oenodeOut{<})(B)! erreicht werden:
% \fi
% \ifENGLISH
% Using relative IDs can be very handy to define a component relative to
% the previous one. It is not possible to use
% e.g. \Lcs{oenodeOut}\opt{\{\}} as reference node, because at the time
% these coordinates are evaluated, they reference to the new, not yet
% defined component. A call like \lstinline!\optbox(\oenodeOut{})(B)!
% is, therefore, not possible and gives an error. With relative IDs one
% can achieve that with \lstinline!\optbox(\oenodeOut{<})(B)!:
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(4,2)
  \psset{optboxsize=0.4 0.8, abspos=0.5}
  \optbox(0,1)(4,1)
  \multido{}{3}{\optbox(\oenodeOut{<})(4,1)}
\end{pspicture}
\end{LTXexample}
% \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 (\compref{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
%  (\compref{optcirculator}).
%  \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[pos=t, linerange={1-3, 4-7}]
\begin{pspicture}(5,1)
  \pnodes(0.5,0.5){A}(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)
  \pnodes(0.5,0.5){A}(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. \Lcomp{optdetector} und \Lcomp{optcoupler} (siehe unten), im
% Mittelpunkt der Komponente.
% \fi
% \ifENGLISH
% This node lays, except for a few components like
% e.g. \Lcomp{optcirculator} and \Lcomp{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 \Lcomp{optcoupler} hängt die Position der Komponentenmitte
% von den \Lkeyword{coupleralign} Einstellungen ab.
% \fi
% \ifENGLISH For \Lcomp{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
%    \pnodes(0,1.25){A}(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}
\begin{LTXexample}[morekeywords={[21]extnodealign}]
\begin{pspicture}(-2.2,-2.2)(2.2,2.2)
  \psset{dotscale=1.5, mirrortype=extended, mirrordepth=0.5, label=0.25 . . relative, extnodealign=abs, extnode=tr}
  \newpsstyle{ExtendedMirror}{}
  \multido{\i=0+45,\ii=-45+45}{8}{%
    \mirror(0,0)(1.5;\i)(2.1212;\ii){\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}
\begin{LTXexample}[morekeywords={[21]extnodealign}]
\begin{pspicture}(-2.2,-2.2)(2.2,2.2)
  \psset{dotscale=1.5, mirrortype=extended, mirrordepth=0.5, label=0.25 . . relative, extnodealign=abs, extnode=tr}
  \newpsstyle{ExtendedMirror}{}
  \multido{\i=0+45,\ii=-45+45}{8}{%
    \mirror(0,0)(1.5;\i)(2.1212;\ii){\i}
    \psdot(\oenodeExt{})
  }%
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \valitem{extnodes}{list}
% \ifGERMAN Erlaubt die Definition mehrerer externer Knoten, \prm{list}
% ist eine Liste von \prm{refpoint}, wie sie von \Lkeyword{extnode}
% verwendet werden. Der erste Knoten kann wie gewohnt mit
% \Lcs{oenodeExt} angesprochen werden (ist äquivalent zu
% \Lcs{oenode}{\{Ext\}} und \Lcs{oenode}{\{Ext1\}}). Für alle weiteren
% Knoten muss \Lcs{oenode} mit den Knotenbezeichnungen
% \opt{Ext}\prm{num} verwendet werden: \Lcs{oenode}\opt{\{Ext1\}} für den
% ersten, \Lcs{oenode}{\{Ext2\}} für den zweiten usw.
% \fi
% \ifENGLISH
% Define multiple external nodes, with their \prm{refpoints} given in
% the \prm{list} and separated by commas. The first node can be accessed
% as usual with \Lcs{oenodeExt} (is equivalent to \Lcs{oenode}{\{Ext\}}
% and \Lcs{oenode}{\{Ext1\}}). All additional nodes must be accessed
% with \Lcs{oenode} and the node label \opt{Ext}\prm{num}:
% \Lcs{oenode}{\{Ext1\}} for the first one, \Lcs{oenode}{\{Ext2\}} for
% the second, etc.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]extnodes}, linerange={1-3,5-5}]
\begin{pspicture}(3,2)
  \optbox[extnodes={tl,tr,br,bl}](0,1)(3,1)
  \multido{\i=1+1}{4}{\psdot[dotstyle=o](\oenode{Ext\i}{})}%
  \multido{\i=1+1,\ii=135+-90}{4}{\uput[\ii](\oenode{Ext\i}{}){Ext\i}}%
\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 der Buchstabe \opt{N} ist. Der letzte Knoten ist immer
%   \opt{N}, kann aber auch über die entsprechende Zahl angesprochen
%   werden.
%   \fi
%   \ifENGLISH
%   The interface node \prm{num}, where the number is a positive integer
%   or the character \opt{N}. The last node is always defined as \opt{N}
%   but can also be accessed via its number.
%   \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
%   (\compref{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 (\compref{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) 
  \pnodes(0,1){A}(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) 
  \pnodes(0,1){A}(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) 
  \pnodes(0,1){A}(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)
  \pnodes(0,1.5){A}(2,1.5){B}(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){}
  \pnodes(\oenodeBeamUp{}){Up1}(\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
%
%   \cmditem{oeBeamCenter}{num}
%
%   \ifGERMAN Damit erhält man die Mitte zwischen oberem und unterem
%   Endknoten, die Koordinaten sind nur aus Postscript-Ebene verfügbar,
%   im Gegensatz zu \Lcs*{oenodeBeam*}, daher auch die an
%   \Lcs*{oeBeamVec*} angelehnte Nomenklatur. Ein Anwendungsbeispiel ist
%   \prettyref{ex:beamcenter}.
%   \fi
%   \ifENGLISH Get the mean of upper and lower beam node. The
%   coordinates are available only at Postscript level, in contrast to
%   the \Lcs*{oenodeBeam*} macros. For an example see 
%   \prettyref{ex:beamcenter}.
%   \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) 
  \pnodes(0,1){A}(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 normalized vectors of the last
% saved beams (see \Lkeyword{savebeam}) can be accessed at 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 Bei den gespeicherten Werten handelt es sich um den
% normierten Richtungsvektor des letzten Strahlsegments, dieser ist nur
% auf Postscript-Ebene verfügbar. Dieser Richtungsvektor ist im
% folgenden Beispiel in rot zu sehen. Im Gegensatz dazu wird mit
% \Lkeyword{savebeam} der Richtungsvektor gespeichert, der nach der
% letzten Grenzfläche gelten würde, also für einen nachfolgenden Strahl
% verwendet würde. Dieser ist im Beispiel in blau eingezeichnet.
% \fi
% \ifENGLISH The saved values are those of the normalized direction
% vector of the last beam segment and are drawn in red in the next example. In contrast
% to this, the vector saved with \Lkeyword{savebeam} is that behind the
% last interface and would be used for a following beam. This is shown
% in blue in the following example.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]beaminsidelast}]
\begin{pspicture}(4,2)
  \optbox[optboxsize=2 1, angle=20, n=2](0,1)(4,1)
  \drawbeam[beaminsidelast, beamalign=abs](0,1){1}
  \pnode(\oenodeBeam{}){Out}
  \nodexn{(Out)+(!\oeBeamVec{})}{C}
  \drawbeam[linecolor=blue, arrows=->, loadbeam]{1}(C)
  \drawbeam[linecolor=red, arrows=->](Out)(C)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN Das Verhalten ist unabhängig davon, ob der letzte Strahl nur
% berechnet, oder auch gezeichnet wurde. Das nächste Beispiel verwendet
% \Lkeyword{stopinside} anstelle vom Parameter \Lkeyword{beaminsidelast}
% im vorangegangenen Beispiel; die Strahlvektoren bleiben davon
% unbeeinflusst.
% \fi
% \ifENGLISH This behaviour is independent of whether the last beam was
% only calculated or also drawn. The next example uses
% \Lkeyword{stopinside} instead of \Lkeyword{beaminsidelast} compared to
% the previous example; the beam vectors are not affected by this.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]stopinside}]
\begin{pspicture}(4,2)
  \optbox[optboxsize=2 1, angle=20, n=2](0,1)(4,1)
  \drawbeam[stopinside, beamalign=abs](0,1){1}
  \pnode(\oenodeBeam{}){Out}
  \nodexn{(Out)+(!\oeBeamVec{})}{C}
  \drawbeam[linecolor=blue, arrows=->, loadbeam]{1}(C)
  \drawbeam[linecolor=red, arrows=->](Out)(C)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN Das kann dazu genutzt werden, um z.B. die Polarisation eines
% Strahls zu kennzeichnen. Im folgenden Beispiel werden die neuen Knoten
% \prm{U} und \prm{L}definiert, indem mit \Lcs*{nodexn} die Endpunkte
% des oberen bzw. unteren Strahls entlang ihrer Trajektorie zurück
% verschoben werden.
% \fi
% \ifENGLISH A possible application is marking of the polarization of a
% beam. In the following example we define the nodes \prm{U} and \prm{L}
% which are shifted with \Lcs*{nodexn} from the end point of the upper
% and lower beam along the respective beam trajectory.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[linerange={1-9,11-11}]
\begin{pspicture}(3,3)
  \pnodes(0,1.5){A}(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
% 
% \begin{ltxsyntax}
%   \cmditem{oeBeamVecMedian}{num}
%   \ifGERMAN Der Mittelwert aus oberem und unterem Strahlvektor.\fi
%   \ifENGLISH The mean of upper and lower beam vector.\fi
% \end{ltxsyntax}
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[caption={caption}, label={ex:beamcenter}]
\begin{pspicture}(3.5,2.6)
  \pnodes(0,2){A}(1,2){B}(3,1){C}
  \optprism(A)(B)(C)
  \newpsstyle{Beam}{linestyle=none, fillstyle=solid, beamwidth=0.2, beamnodealign=vector}
  \drawwidebeam[fillcolor=orange](A){}
  \psset[optexp]{beampathskip=1}
  \drawwidebeam[fillcolor=green, n=1.2, savebeam=2](A){}(C)
  \drawwidebeam[fillcolor=red, n=1.4, savebeam=3](A){}(C)
  \drawwidebeam[fillcolor=red!50!black, n=1.57, savebeam=4](A){}(C)
  \multido{\i=2+1}{3}{%
    \backlayer{%
      \pnode(!\oeBeamCenter{\i}){Det\i}
      \nodexn{(Det\i)-(!\oeBeamVecMedian{\i})}{Det\i'}}
    \optdetector[detsize=0.4 0.4](Det\i')(Det\i)}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN Weitere Anwendungsbeispiele sind \prettyref{ex:glan-thompson} und \prettyref{ex:wgm-pdc}.\fi
% \ifENGLISH Further example are \prettyref{ex:glan-thompson} and \prettyref{ex:wgm-pdc}.\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,17-17}]
\psset{unit=2}
\begin{pspicture}(0.3,0.1)(4.8,1.6)
  \pnodes(0.5,0.5){A}(4.5,0.5){B}
  \optbox[compshift=0.5, angle=10, rotateref=tr, extnode={-0.5,1}](A)(B)
  \psline[style=Refline](\oenodeTrefA{})(\oenodeTrefB{})
  \psline[style=Refline, linestyle=dashed](\oenodeRefA{})(\oenodeRefB{})
  \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 Lichtstrahlen,
% Fasern oder Drähten 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 wird in \prettyref{sec:drawbeam} beschrieben.
% \item \prettyref{sec:drawwidebeam} erweitert diese Beschreibung von
%   Strahlverbindungen auf ausgedehnte Strahlen und deren Eigenheiten.
% \item In \prettyref{sec:error-handling} wird gezeigt, wie fehlerhafte
%   Strahlverbindungen (verfehlen von Grenzflächen) gehandhabt wird).
% \item \prettyref{sec:custombeam} erläutert, wie bestimmte, stückweise
%   definierte Strahlengänge, wie z.B. bei eine Teleskop, einfach
%   realisiert werden können.
% \item Manuelle Faserverbindungen werden in \prettyref{sec:drawfiber}
%   behandelt, manuelle elektrischen Verbindungen, die sehr ähnlich
%   funktionieren, in \prettyref{sec:drawwire}.
% \item Automatische Verbindungen werden in
%   \prettyref{sec:drawconn-auto} erklärt.
% \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 connections of components with beams, fibers, or wires.
% \begin{compactitem}
% \item \prettyref{sec:accessobj} describes how to access objects and
%   nodes for use with the connection macros.
% \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 and their special properties.
% \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, like e.g. in a telescope, can be easily
%   constructed.
% \item Manual fiber connections are described in
%   \prettyref{sec:drawfiber}, manual wire connections, which show the
%   same behavior, are treated in \prettyref{sec:drawwire}.
% \item Automatic connections are explained in
%   \prettyref{sec:drawconn-auto}.
% \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)
  \pnodes(0,1){A}(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 
% Es 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 You can also use number ranges, 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, an ID range, a \Lkeyword{compname}, or a PSTricks nodes (see
%   \prettyref{sec:accessobj}). 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 ID-Intervall, ein \Lkeyword{compname} oder
%   ein PSTricks-Knoten sein können (siehe \prettyref{sec:accessobj}. 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 \Lcomp{optprism} and \Lcomp{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 \Lcomp{optprism} oder \Lcomp{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)
  \pnodes(0,1.5){A}(1,1.5){B}(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 \Lcomp{doveprism} the same applies as for the \Lcomp{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 \Lcomp{doveprism} wird im Prinzip genauso behandelt wie das \Lcomp{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)
  \pnodes(0,1){A}(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)
  \pnodes(0,1){A}(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)
  \pnodes(0,1){A}(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)
  \pnodes(0,0.5){A}(2.5,0.5){B}(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 \Lcomp{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 \Lcomp{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)
  \pnodes(0,1){A}(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)
  \pnodes(0,1){A}(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)
  \pnodes(0,1.5){A}(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)
  \pnodes(-1,0){A}(1,2.2){B}(3,0){C}
  \optplane(0,2.15)
  \optprism[prismalign=center, prismangle=59](A)(B)(C)
  \optplane(C)
  \definecolor[ps]{bl}{rgb}{%
    tx@addDict begin tx@OptexpDict begin
      Wavelength wavelengthToRGB 
      Red Green Blue 
    end end }%
  \addtopsstyle{Beam}{linecolor=bl, linewidth=0.4\pslinewidth, beamalign=abs}
  \multido{\iLambda=400+4}{60}{%
    \pstVerb{/Wavelength \iLambda\space def }%
    \drawbeam[n=Wavelength 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)
  \pnodes(0.3,1){A}(2,1){B}(3,2){C}(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)
  \pnodes(1.5,0.5){A}(3.5,0.5){B}(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)
  \pnodes(1.5,0.5){A}(3.5,0.5){B}(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, firstcomp}
% \ifGERMAN
% Gibt vor, ob der Winkel \Lkeyword{beamangle} relativ zu der Verbindung
% zwischen den ersten beiden Komponenten ist, ob es sich um einen
% absoluten Winkel handelt, oder ob der Winkel durch die Ausrichtung der
% ersten Komponente vorgegeben wird.
%
% 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)
  \pnodes(0,0.75){A}(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
%
% \ifGERMAN 
% Im folgenden Beispiel liegen beide Komponenten auf der horizontalen
% Linie $\overline{AB}$. Der grüne Strahl, mit
% \Lkeyword{beamalign}\opt{=rel} verläuft daher auch horizontal. Der
% rote Strahl ist hingegen mit \Lkeyword{beamalign}\opt{=firstcomp}
% entsprechend der Drehung der ersten Komponente ausgerichtet.
% \fi
% \ifENGLISH 
% Both components in the following example are align on the horizontal
% line $\overline{AB}$. The green beam with
% \Lkeyword{beamalign}\opt{=rel} is accordingly aligned
% horizontally. The red beam with \Lkeyword{beamalign}\opt{=firstcomp}
% is aligned according to the rotation of the first component:
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords = {[21]{beamalign, angle}}]
\begin{pspicture}(4,3)
  \pnodes(1.5,1.5){A}(4,1.5){B}
  \optbox[position=start, rotateref=r, angle=10](A)(B)
  \optplate[position=end, plateheight=3](A)(B)
  \addtopsstyle{Beam}{beamdiv=20}
  \drawwidebeam{-}
  \drawwidebeam[beamalign=firstcomp, linecolor=red]{-}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \numitem[0]{beampathskip}
% \ifGERMAN
% Überspringt \prm{num} Segmente am Anfang des Strahlengangs. Diese
% Option beinflusst lediglich ab welchem Segment der Strahlgang
% gezeichnet wird, das Raytracing beginnt immer noch an der ersten
% Grenzfläche. Um das zu ändern können Sie \Lkeyword{startinsidecount}
% verwenden.
% \fi
% \ifENGLISH
% Skip \prm{num} segments at the beginning of the beam path. This option
% determines only at which segment the beam is drawn, the ray tracing
% always starts at the first interface. To change this, see option
% \Lkeyword{startinsidecount}.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords = {[21]{beampathskip}}, pos=t]
\begin{pspicture}(5,2)
\pnodes(0,1){A}(5,1){B}(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
%
% \numitem[-1]{beampathcount}
% \ifGERMAN
% Anzahl der Strahlsegmente, die gezeichnet werden sollen. Werden am
% Anfang Segmente mit \Lkeyword{beampathskip} übersprungen, so werden
% diese nicht mitgezählt. 
% \fi
% \ifENGLISH
% Number of beam segments, which are drawn. Segments which are skipped
% at the beam start with \Lkeyword{beampathskip} do not count.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords = {[21]{beampathcount}}]
\begin{pspicture}(3,2)
  \pnodes(0,2){A}(2,0.8){B}(4,2){C}
  \optprism[compname=P, prismtype=reflective, prismangle=90](A)(B)(C)
  \lens[abspos=1.33](\oenodeIfc{2}{P})(A)%
  \drawwidebeam[beamwidth=0.2, beaminsidelast, beampathcount=4](A){2}{1}
\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. \Lcomp{optfilter} und \Lcomp{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. \Lcomp{optfilter} and \Lcomp{optdiode}).
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords = {[21]{allowbeaminside}}]
\begin{pspicture}(3,2)
  \psset{optboxwidth=0.5}
  \pnodes(0,1){A}(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}
  \pnodes(0,1){A}(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
%
% \numitem[-1]{startinsidecount}
% \ifGERMAN
% Anzahl der Segmente, die innerhalb der ersten Komponente verwendet
% werden. Diese Option hat nur eine Wirkung, wenn
% \Lkeyword{beaminsidefirst} oder \Lkeyword{startinside} auf \opt{true}
% gesetzt sind.
% \fi
% \ifENGLISH
% Number of segments, which are used inside the first component. This
% option is in effect only with \Lkeyword{beaminsidefirst} or
% \Lkeyword{startinside} set to \opt{true}.
% \fi
%
% \numitem[-1]{stopinsidecount}
% \ifGERMAN
% Anzahl der Segmente, die innerhalb der letzten Komponente verwendet
% werden. Diese Option hat nur eine Wirkung, wenn
% \Lkeyword{beaminsidelast} oder \Lkeyword{stopinside} auf \opt{true}
% gesetzt sind.
% \fi
% \ifENGLISH
% Number of segments, which are used inside the last component. This
% option is in effect only with \Lkeyword{beaminsidelast} or
% \Lkeyword{stopinside} set to \opt{true}.
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords = {[21]{stopinsidecount, startinsidecount}}]
\begin{pspicture}(4,2)
  \pnodes(0,2){A}(2,0){B}(4,2){C}
  \optprism[compname=P, n=1, prismtype=reflective, prismangle=90](A)(B)(C)
  \lens[abspos=1.08](\oenodeIfc{2}{P})(A)
  \lens[abspos=1.08](\oenodeIfc{2}{P})(C)
  \newpsstyle{Beam}{linestyle=none, fillstyle=solid}
  \drawwidebeam[fillcolor=green, beamwidth=0.2, beaminsidelast, stopinsidecount=1](A){2}{1}
  \drawwidebeam[fillcolor=orange, beaminsidefirst, startinsidecount=1, loadbeam]{1}{3}(C)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \choitem[auto]{beammode}{refl, trans, reflective, transmittive, auto}
% \ifGERMAN 
% Mit dieser Option kann das Strahlverhalten bei Komponenten wie
% z. B. dem \Lcomp{beamsplitter} auf reflektierend oder transmittierend
% festgelegt werden, unabhängig von den verwendeten Knoten und deren
% relative Position bezüglich der Komponente.
% \fi
% \ifENGLISH
% With this option one can force the beam path through e.g. a
% \Lcomp{beamsplitter} to \opt{reflective} or \opt{transmittive}
% independent of the choosen nodes and their position relative to the
% component.
% \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 a plane, which can be created
% automatically or manually in different ways.
% \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, die auf unterschiedliche Weise automatisch oder manuell
% erstellt werden kann.
% \fi
%
% \begin{optionlist}
% \choitem[connection]{beamnodealign}{vec, conn, vector, connection}
% \ifENGLISH
% This parameter controls the alignment of the automatically created
% node interfaces. By default (\opt{connection}) the interface is
% aligned perpendicular to the direct connection between node and the
% previous interface node.
% \fi
% \ifGERMAN 
% Dieser Parameter bestimmt die Ausrichtung der automatisch erstellen
% Grenzflächen. In der Voreinstellung (\opt{connection}) wird die Ebene
% vertikal zur direkten Verbindung zwischen dem Knoten und dem
% vorangegangenen Grenzflächenknoten ausgerichtet.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2)
  \pnodes(0,1){A}(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}
\begin{LTXexample}
\begin{pspicture}(3,2)
  \pnodes(0,1){A}(3,1){B}
  \lens[abspos=0.5](A)(B)
  \addtopsstyle{Beam}{linecolor=black, fillstyle=solid, beamwidth=0.2, fillcolor=red, opacity=0.5, beaminside=false}
  \multido{\r=-0.3+0.3}{3}{\drawwidebeam[beampos=\r](A){}(B)}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN 
% Ist der Wert auf \opt{vector} gesetzt, dann wird die Ebene vertikal
% zum einfallenden Strahlvektor ausgerichtet. Bei weiten Strahlen wird
% der gemittelte Strahlenvektor (siehe \Lcs{oeBeamVecMedian}) als
% Referenz verwendet. Beispiele in dem das sehr praktisch ist, sind
% \prettyref{ex:beamcenter} und \prettyref{ex:wgm-pdc}.
% \fi
% \ifENGLISH
% For a value \opt{vector}, the plane is aligned vertical to the
% incoming beam vector. For wide beams the mean beam vector is used (see
% \Lcs{oeBeamVecMedian}). Examples where this is very convenient are
% \prettyref{ex:beamcenter} and \prettyref{ex:wgm-pdc}.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]beamnodealign}]
\begin{pspicture}(3,2)
  \pnodes(0,1){A}(3,1){B}
  \lens[abspos=0.5](A)(B)
  \addtopsstyle{Beam}{linecolor=black, fillstyle=solid, beamwidth=0.2, beamnodealign=vector, fillcolor=green, opacity=0.5, beaminside=false}
  \multido{\r=-0.3+0.3}{3}{\drawwidebeam[beampos=\r](A){}(B)}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{optionlist}
%
% \ifENGLISH
% The automatic alignment is very handy in many cases, but does not
% allow to rotate the node planes to a fixed angle and can give again
% problems with shifted and rotated components (see
% \prettyref{sec:rotshift}). In the following example the green beam is
% with \Lkeyword{beamnodealign} set to \opt{vector}, for the red beam it
% is set to \opt{connection}:
% \fi
% \ifGERMAN
% Die automatische Ausrichtung 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. Im folgenden Beispiel ist beim grünen Strahl
% \Lkeyword{beamnodealign} auf \opt{vector} gesetzt, bei dem roten
% Strahl hingegen auf \opt{connection}:
% \fi
%
% \hspace*{\fill}%
% \begin{pspicture}(4,2.7)
%   \pnodes(0,0.5){A}(4,0.5){B}
%   \lens[compshift=0.5, abspos=1, lens=1.5 1.5 2](A)(B)
%   \drawwidebeam[beamalign=absolute, linecolor=black, fillstyle=solid, beamwidth=0.6, fillcolor=green, opacity=0.5, beamnodealign=vector](A){}(B)
%   \rput[rb](4,0){\ttfamily vector}
% \end{pspicture}
% \hspace*{1cm}%
% \begin{pspicture}(5,3)
%   \pnodes(0,0.5){A}(4,0.5){B}
%   \lens[compshift=0.5, abspos=1, lens=1.5 1.5 2](A)(B)
%   \drawwidebeam[beamalign=absolute, linecolor=black, fillstyle=solid, beamwidth=0.6, fillcolor=red, opacity=0.5](A){}(B)
%   \rput[rb](5,0){\ttfamily connection}
% \end{pspicture}
% \hspace*{\fill}%
%
% \ifENGLISH
% For more flexibility, the package provides an «invisible» plane which
% can be used for this purpose.
% \fi
% \ifGERMAN
% Das kann mit einer «unsichtbaren» Ebene erreicht werden, die mit
% \Lcomp{optplane} definiert wird.
% \fi
%
% \begin{ltxsyntax}
%   \xLcomp{optplane}\compitem{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)
  \pnodes(0,1){A}(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 connections}\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
% \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 \nxLcs{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 \nxLcs{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 
%   \nxLcs{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 
%   \nxLcs{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)
  \pnodes(0,1.5){A}(2,1.5){B}(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
%
% \begin{stylelist}
% \typeitem{fade}{\prm{linestyle}}
% \ifENGLISH 
% Fade from the current \opt{linecolor} to another color, defined by
% \Lkeyword{fadeto}. The line style currently works only for line, not
% for curves. The complete path is divided in \Lkeyword{fadepoints}$ -
% 1$ segments.
% \fi
% \ifGERMAN
% Erzeugt einen Farbverlauf von der aktuellen \opt{linecolor} zu einer
% anderen Farbe, definiert durch \Lkeyword{fadeto}. Der Linienstil
% funktioniert momentan nur vernünftig mit Linien, nicht jedoch mit
% Kurven. Der gesamte Pfad wird in \Lkeyword{fadepoints}$- 1$ Segmente
% unterteilt.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1)
  \psline[linewidth=0.2, linecolor=red, linestyle=fade, fadepoints=50](0,0.5)(3,0.5)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{stylelist}
% \begin{optionlist}
% \choitem[white]{fadeto}{white, black, transparency}
% \ifENGLISH 
% The color at the fade end, depends on \Lkeyword{fadefuncname} and
% \Lkeyword{fadefunc}.
% \fi
% \ifGERMAN
% Die Endfarbe des Farbverlaufs, hängt auch von \Lkeyword{fadefuncname}
% und \Lkeyword{fadefunc} ab.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1)
  \psset{linewidth=0.2, linecolor=red, linestyle=fade, fadepoints=50}
  \psline[fadeto=white](0,0.9)(3,0.9)
  \psline[fadeto=black](0,0.5)(3,0.5)
  \psline[fadeto=transparency](0,0.1)(3,0.1)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \numitem[200]{fadepoints}
% \ifENGLISH
% Number of points used for lines with style \opt{fade}.
% \fi
% \ifGERMAN
% Anzahl der Punkte, die für den Linienstil \opt{fade} verwendet werden.
% \fi
%
% \choitem[linear]{fadefuncname}{gauss, linear, squared, exp, custom}
% \ifENGLISH 
% Some predefined fade functions, which determine the color gradient. If
% set to \opt{custom}, the Postscript code in \Lkeyword{fadefunc} is
% used.
% \fi
% \ifGERMAN
% Ein paar vordefinierte Funktionen, die den Farbverlauf bestimmen. Wird
% \opt{custom} angegeben, dann wird der Postscript-Code aus
% \Lkeyword{fadefunc} verwendet.
% \fi
%
% \valitem{fadefunc}{PS code}
% \ifENGLISH 
% Define a custom gradient for line style \Lkeyword{fade}. The \prm{PS
% code} must evaluate a number on the stack in the range $[0,1]$ (0:
% path start, 1: path end) to $[0,1]$ (0: \Lkeyword{fadeto} color, 1:
% current line color). The function values are clipped to $[0,1]$.
% \fi
% \ifGERMAN
% Eine benutzerdefinierte Funktion für den Farbverlauf des Linienstils
% \Lkeyword{fade}. Der \prm{PS code} muss eine Zahl auf dem Stack im
% Intervall $[0,1]$ (0: Pfadanfang, 1: Pfadende) auf das Intervall $[0,
% 1]$ abbilden (0: \Lkeyword{fadeto}-Farbe, 1: aktuelle
% Linienfarbe). Die Funktionswerte werden auf das Intervall $[0, 1]$
% abgeschnitten.
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1)
  \psset{linewidth=0.2, linecolor=red, linestyle=fade, fadepoints=50}
  \psline[fadefuncname=gauss](0,1)(3,1)
  \psline[fadefuncname=exp](0,0.7)(3,0.7)
  \psline[fadefuncname=custom, fadefunc={360 mul cos 1 add 0.5 mul}](0,0.4)(3,0.4)
  \psline[fadefuncname=custom, fadefunc={neg 1 add 2 mul}](0,0.1)(3,0.1)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifENGLISH For a nice example see \prettyref{ex:dsotm}.\fi
% \ifGERMAN Ein schönes Beispiel ist \prettyref{ex:dsotm}.\fi
% \end{optionlist}
% 
% \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)
  \pnodes(1.5,0.5){A}(3.5,0.5){B}(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)
  \pnodes(0,1){A}(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)
  \pnodes(0,0.5){A}(1,0.5){B}(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)
  \pnodes(0,0.5){A}(1,0.5){B}(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)
  \pnodes(0,0.5){A}(1,0.5){B}(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
% Alle Strahlen werden direkt mit Postscript berechnet und gezeichnet,
% so dass eine umfassende Fehlerbehandlung zur Zeit der Kompilation
% nicht möglich ist. 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, Totalreflektion auftritt oder wenn die
% folgende Komponente keine Freistrahlverbindungen unterstützt. Die
% folgenden Beispiele zeigen Situationen, in denen diese Fehler
% auftreten:
% \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)
  \pnodes(0,1){A}(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 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)
  \pnodes(0,2){A}(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
%
% \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
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2.5)
  \pnodes(0,2){A}(3,0){B}
  \optplane(A)
  \optprism[n=1.8](A)([Xnodesep=1.5]A)(B)
  \optplane(B)
  \drawwidebeam[beamdiv=10, linecolor=red]{-}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \item 
%   \ifGERMAN Eine Komponente soll verbunden werden, die jedoch keine
%   Freistrahlverbindungen unterstützt. In diesem Fall wird die falsche
%   Komponente und alle Folgenden ignoriert.
%   \fi
%   \ifENGLISH A component is to be connected, which does not support
%   free-ray connections. In this case, the wrong component and all
%   following ones are ignored.
%   \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,2.7)
  \pnodes(0,1){A}(2,1){B}
  \optplate[position=start](A)(B)
  \lens[lens=4 4 2, abspos=0.5, n=2.5](A)(B)
  \fiberdelayline[fdlsize=1 0.7, position=end, fiber=none](A)(B)
  \drawbeam[beampos=0.2, linecolor=red]{-}
  \drawbeam[beampos=-0.2, linecolor=blue, beaminsidelast]{-}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{enumerate}
%
% \begin{optionlist}
%   \boolitem[false]{pswarning} 
%   \ifENGLISH To simplify debugging, you can have a message printed out
%   if any of these situations arises. The message will be printed to
%   standard output, when a Postscript interpreter reads the file,
%   e.g. when you view the file, or you convert it with \opt{ps2pdf} or
%   similar.
%   \fi
%   \ifGERMAN Um eine Fehlersuche zu vereinfachen kann ein Hinweis
%   ausgegeben werden sobald ein Strahlengang vorzeitig beendet. Die
%   Fehlermeldung wird auf die Standardausgabe geschrieben, wenn die
%   Datei mit einem Postscript-Interpreter gelesen wird, also mit einem
%   Betrachter geöffnet oder z.B. mit \opt{ps2pdf} konvertiert wird.
%   \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
% In principal, all kind of beam paths can be realized with an
% appropriate choice of refractive index and component parameters
% (e.g. lens curvature). This can become very cumbersome, so that the
% package provides the means to simplify this. The end points of one
% beam path can be used 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, siehe z.B. \prettyref{ex:ratchet}. In
%   der Regel reicht an- und abschalten vollkommen aus, was den Zahlen 1
%   und 0 entspricht.
%   \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, see
%   e.g. \prettyref{ex:ratchet}. But in most cases enabling (1) and
%   disabling (0) 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 no divergence at the
% input and output. Usually we would need to tweak the refractive index and the
% lens parameters to get an output beam without 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) 
  \pnodes(0,1){A}(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)
  \pnodes(0,0.5){A}(2,0.5){B}(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}
%   \choitem[true]{savebeam}{true,false,\prm{int}}
%   \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
%
%   \choitem[false]{loadbeam}{true,false,\prm{int}}
%   \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)
  \pnodes(0,0.5){A}(2,0.5){B}(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}, morekeywords={[21]{savebeam, loadbeam}}]
\begin{pspicture}(3,1.5)
  \pnodes(0,0.5){A}(1.5,1.5){B}(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}, morekeywords={[21]{savebeam, loadbeam}}]
\begin{pspicture}(3,1.5)
  \pnodes(0,0.5){A}(1.5,1.5){B}(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 in \prettyref{chap:fibercomp} are connected automatically.
% \fi
% \ifGERMAN
% Alle Komponenten können mit Fasern verbunden werden, die Faserkomponenten
% in \prettyref{chap:fibercomp} werden automatisch verbunden.
% \fi
%
% \begin{ltxsyntax}
%   \xLcs{drawfiber}\cmditem{drawfiber}[options]{obj$_1$}{obj$_2$}\ldots
% \end{ltxsyntax}
%   \ifENGLISH
%   This macro draws fiber connections and takes a variable number of
%   arguments (minimum of two) which can be either an ID, an ID range, a
%   \Lkeyword{compname}, or a PSTricks node (see
%   \prettyref{sec:accessobj}). To distinguish between nodes and
%   components, nodes must be either enclosed in parenthesis within the
%   brackets, or enclosed only in parenthesis:
%   \Lcs{drawfiber}\opt{\{(node)\}\{comp\}}, or
%   \Lcs{drawfiber}\opt{(node)\{comp\}}. If you specify more than two
%   arguments, it draws the 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 
%   Dieses Makro zeichnet Faserverbindungen und akzeptiert eine variable
%   Anzahl an Argumenten (mindestens zwei), die entweder eine ID, ein
%   ID-Intervall, ein \Lkeyword{compname} oder ein PSTricks-Knoten sein
%   können (siehe \prettyref{sec:accessobj}. 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\}}. 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:drawconn-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:drawconn-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)
  \pnodes(0,1){A}(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 blue 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 blauen 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=->, ArrowInsidePos=0.3, 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=blue}
  \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 orientation of
% 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-4,9-10}]
\begin{pspicture}(0,-0.8)(7,0.8)
  \pnodes(0,0){A}(3,0){B}(4,0){C}(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-4,9-10}]
\begin{pspicture}(1,-1.7)(7,1.7)
  \pnodes(0,0){A}(4,0){B}(3,0){C}(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 \Lcomp{optcirculator} and
%   \Lcomp{elecmixer}. 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 \Lcomp{optcirculator} und \Lcomp{elecmixer}
%   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)
  \pnodes(0,0){A}(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
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]fiberangleA, fiberangleB}, linerange={1-3,7-9}]
\begin{pspicture}(0,-1)(4,1)
  \pnodes(0,0){A}(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[fiberangleA=-90](A){}
  \drawfiber[fiberangleB=-90]{}(B)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \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}[linerange={1-1,3-6}]
\begin{pspicture}(3,2)
  \psset{label=0, optboxwidth=1}
  \pnodes(-0.5,1){A}(1.5,1){B}(3.5,1){C}
  \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}[linerange={1-1,3-6}]
\begin{pspicture}(2,2)
  \psset{label=0}
  \pnodes(0,0.5){A}(2,0.5){B}([offset=1]B){C}(A|C){D}
  \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)
  \psset{label=0}
  \pnodes(0,0.5){A}(2,0.5){B}([offset=1]B){C}(A|C){D}
  \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)
  \pnodes(0,0){A}(2,0){B}(0.3,3){C}(1.7,3){D}
  \psset{fiber=none, arrowscale=1.2, arrowinset=0}
  \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{stylelist}
%   \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
% \end{stylelist}
% \begin{optionlist}
%   \valitem{addtoFiber}{list}
%     \addtostylemsg{Fiber}
%   \ifGERMAN Siehe z.B. \prettyref{ex:recirc-loop}.\fi
%   \ifENGLISH See for example \prettyref{ex:recirc-loop}.\fi
%
%   \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)
  \pnodes(1, 0.5){A}(2.5,0.5){B}(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)
  \pnodes(1,2.5){In}(3,2.5){Out}(0,2){A}(4,2){B}(4,0){C}(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}
%
% \ifGERMAN\section{Elektrische Verbindungen}\fi
% \ifENGLISH\section{Drawing wires}\fi
% \label{sec:drawwire}
%
% \ifENGLISH 
% All available components can be connected with wire connections, the
% wire components in \prettyref{chap:electrcomp} are connected
% automatically. The \Lkeyword*{wire*} parameters are equivalent to
% their \Lkeyword*{fiber*} counterparts, see their respective
% documentation for details.
% \fi
% \ifGERMAN
% Alle Komponenten können mit Drähten verbunden werden, die elektrischen
% Komponenten in \prettyref{chap:electrcomp} werden automatisch
% verbunden. Die \Lkeyword*{wire*}-Parameter sind äquivalent zu den
% entsprechenden \Lkeyword*{fiber*}-Parametern, die detailliertere
% Informationen enthalten.
% \fi
%
% \begin{ltxsyntax}
%   \xLcs{drawwire}\cmditem{drawwire}[options]{obj$_1$}{obj$_2$}\ldots
% \end{ltxsyntax}
%   \ifENGLISH
%   This command can take a variable number of arguments (minimum of
%   two) which can be either an ID, an ID range, a \Lkeyword{compname},
%   or a PSTricks nodes (see \prettyref{sec:accessobj}). To distinguish
%   between nodes and components, nodes must be either enclosed in
%   parenthesis within the brackets, or enclosed only in parenthesis:
%   \Lcs{drawwire}\opt{\{(node)\}\{comp\}}, or
%   \Lcs{drawwire}\opt{(node)\{comp\}}. If you specify more than two
%   arguments, you get connections $1\rightarrow 2$, $2\rightarrow 3$,
%   and so on.
%
%   The automatic connections are drawn internally with
%   \Lcs{drawwire} commands from each reference node to the component.
%   \fi
%   \ifGERMAN 
%   Dieses Makro akzeptiert eine variable Anzahl an Argumenten
%   (mindestens zwei), die entweder eine ID, ein ID-Intervall, ein
%   \Lkeyword{compname} oder ein PSTricks-Knoten sein können (siehe
%   \prettyref{sec:accessobj}. 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\}}. Werden mehr als zwei Argumente
%   mitgegeben, werden die Verbindungen $1\rightarrow 2$, $2\rightarrow
%   3$, usw. gezeichnet.
%
%   Die automatischen Verbindungen werden intern als
%   \Lcs{drawwire} von den Referenzknoten zur Komponente gezeichnet.
%   \fi
%
% \begin{optionlist}
%   \choitem[relative]{wirealign}{rel,relative,center,abs,absolute}
%   \ifGERMAN Siehe \Lkeyword{fiberalign}.\fi
%   \ifENGLISH See \Lkeyword{fiberalign}.\fi
%
%   \numitem[0]{wireangleA}
%   \ifGERMAN Siehe \Lkeyword{fiberangleA}.\fi
%   \ifENGLISH See \Lkeyword{fiberangleA}.\fi
%
%   \numitem[0]{wireangleB}
%   \ifGERMAN Siehe \Lkeyword{fiberangleB}.\fi
%   \ifENGLISH See \Lkeyword{fiberangleB}.\fi
%
%   \valitem[angle]{wirestyle}{string}
%   \ifGERMAN Siehe \Lkeyword{fiberstyle}, der Vorgabewert ist jedoch \opt{angle}.\fi
%   \ifENGLISH See \Lkeyword{fiberstyle}, the default value is \opt{angle}.\fi
%
%   \valitem{addtoWire}{list}
%     \addtostylemsg{Wire}
%
%   \valitem{newWire}{list}
%     \newstylemsg{Wire}
% \end{optionlist}
% \begin{stylelist}
%   \styleitem{Wire}
%   \ifENGLISH
%   The appearance of wires is controlled with this style, compare with
%   \prettyref{sec:fiberappearance}. The optional argument of
%   \Lcs{drawwire} can be used as well, these options can overwrite
%   settings from the \Lstyle{Wire} style.
%   \fi
%   \ifGERMAN
%   Das Aussehen der elektrischen Verbindungen wird durch diesen Stil
%   vorgegeben, analog zu \prettyref{sec:fiberappearance}. Das optionale
%   Argument von \Lcs{drawwire} kann ebenfalls verwendet werden, die
%   entsprechenden Parameter können die Einstellungen von \Lstyle{Wire}
%   überschreiben.
%   \fi
%   \end{stylelist}
%   
% \ifENGLISH\section{Automatic fiber and wire connections}\fi
% \ifGERMAN\section{Automatische Faser- und Drahtverbindungen}\fi
% \label{sec:drawconn-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
% electrical components (\prettyref{chap:electrcomp}) are accordingly
% connected with \Lcs{drawwire}. The connections can also be controlled
% in a number of ways, without explicitely using these macros. The style
% of each connection can be configure independently, see
% \prettyref{sec:drawconn-auto-styles}.
% \fi
% \ifGERMAN
% Alle Faserkomponenten, die in \prettyref{chap:fibercomp} beschrieben
% werden, werden automatisch über \Lcs{drawfiber} mit ihren
% Referenzknoten verbunden, das Verhalten ist in
% \prettyref{sec:drawfiber-angles} beschrieben. Entsprechend dazu werden
% die elektrischen Komponenten (\prettyref{chap:electrcomp}) mit
% \Lcs{drawwire} mit Drähten verbunden. Die automatischen Verbindungen
% können umfangreich kontrolliert werden, ohne diese Makros explizit zu
% verwenden. Das Aussehen jeder Verbindung kann ebenfalls separat
% konfiguriert werden, siehe \prettyref{sec:drawconn-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
%   and electrical components (prefixed with \opt{+}), or all component types
%   otherwise. Typical free-ray components which are often used with
%   fibers as well are \Lcomp{optbox} and \Lcomp{optdetector}. Please
%   note, that electrical components cannot be connected automatically
%   with fibers, in these cases you must use \Lcs{drawfiber}
%   explicitely.
%
%   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 \Lcomp{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 elektrischen und
%   Freistrahlkomponenten (\opt{+} wird vorangestellt), oder alle
%   Komponententypen. Typische Freistrahlkomponenten, die häufig als
%   Faserkomponenten verwendet werden, sind \Lcomp{optbox} und
%   \Lcomp{optdetector}. Beachten Sie, dass elektrische Komponenten
%   nicht automatisch mit Fasern verbunden werden können, Sie müssen
%   dann explizit \Lcs{drawfiber} verwenden.
%
%   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 \Lcomp{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 all components.\fi
%   \ifGERMAN Zeichne alle Fasern für alle Komponenten.\fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{fiber}}]
\begin{pspicture}(3,3)
  \psset{fiber}
  \optbox(0,2.5)(3,2.5)
  \optmzm(0,1.5)(3,1.5)
  \elecsynthesizer[position=0.5](0,0.5)(3,0.5)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \item 
%   \ifENGLISH Draw only the input fiber of a fiber component (\Lcomp{optmzm}),
%   the other components are not affected.
%   \fi
%   \ifGERMAN Nur die Eingangsverbindung einer Faserkomponente (\Lcomp{optmzm})
%   wird gezeichnet, die anderen Komponenten bleiben unbeeinflusst.
%   \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{fiber}}]
\begin{pspicture}(3,3)
  \psset{fiber=*i}
  \optbox(0,2.5)(3,2.5)
  \optmzm(0,1.5)(3,1.5)
  \elecsynthesizer[position=0.5](1,0.5)(3,0.5)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \item 
%   \ifENGLISH All connections of the fiber component are drawn, the
%   other components get only the output fiber.
%   \fi
%   \ifGERMAN Von der Faserkomponente werden alle Verbindungen
%   gezeichnet, die anderen Komponenten erhalten nur eine
%   Ausgangsverbindung.
%   \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{fiber}}]
\begin{pspicture}(3,3)
  \psset{fiber=+o}
  \optbox(0,2.5)(3,2.5)
  \optmzm(0,1.5)(3,1.5)
  \elecsynthesizer[position=0.5](1,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 \Lcomp{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 \Lcomp{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}
%
% \begin{optionlist}
%   \choitem[all]{wire}{[*+]none,all,i,o,\prm{refpoint}}
%   \ifENGLISH 
%   This parameter selects which wire connections are drawn. The value
%   of this parameter can affect either only the electrical components
%   (if the value is prefixed with \opt{*}), only free-ray and fiber
%   components (prefixed with \opt{+}), or all components otherwise.
%   \fi
%   \ifGERMAN
%   Dieser Parameter gibt an, welche elektrische Verbindungen gezeichnet
%   werden. Der Parameter kann nur die elektrischen Komponenten
%   betreffen (falls ein \opt{*} vorangestellt ist), nur die Faser- und
%   Freistrahlkomponenten (\opt{+} wird vorangestellt), oder alle
%   Komponenten.
%   \fi
% \end{optionlist}
% \begin{enumerate}
% \item 
%   \ifENGLISH Enable all wire connections for all components.\fi
%   \ifGERMAN Zeichne alle Drähte aller Komponenten.\fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{wire}}]
\begin{pspicture}(3,3)
  \psset{wire}
  \optbox(0,2.5)(3,2.5)
  \optmzm(0,1.5)(3,1.5)
  \elecsynthesizer[position=0.5](0,0.5)(3,0.5)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \item 
%   \ifENGLISH Draw only the input wire of an electrical component
%   (\Lcomp{elecsynthesizer}), the other components are not affected.
%   \fi
%   \ifGERMAN Nur die Eingangsverbindung einer elektrischen Komponente
%   (\Lcomp{elecsynthesizer}) wird gezeichnet, die anderen Komponenten
%   bleiben unbeeinflusst.
%   \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{wire}}]
\begin{pspicture}(3,3)
  \psset{wire=*i}
  \optbox(0,2.5)(3,2.5)
  \optmzm(0,1.5)(3,1.5)
  \elecsynthesizer[position=0.5](0,0.5)(3,0.5)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% 
% \item 
%   \ifENGLISH Draw only the output wire of the free-ray and fiber
%   components, but all connections of the wire component.
%   \fi
%   \ifGERMAN Von der Freistrahl- und Faserkomponente wird nur die Ausgangsverbindung
%   gezeichnet, die elektrischen Komponente erhält jedoch alle Verbindungen.
%   \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{wire}}]
\begin{pspicture}(3,3)
  \psset{wire=+o}
  \optbox(0,2.5)(3,2.5)
  \optmzm(0,1.5)(3,1.5)
  \elecsynthesizer[position=0.5](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 connections, i.e \Lcomp{elecmixer} and \Lcomp{eleccoupler}.
%   \fi
%   \ifGERMAN
%   Die Werte \opt{t} und \opt{b} betreffen nur die Komponenten mit mehr als
%   zwei Verbindungen, also \Lcomp{elecmixer} und \Lcomp{eleccoupler}.
%   \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{wire}}]
\begin{pspicture}(3,1)
  \eleccoupler[wire=t](0,1)(0,0)(3,1)(3,0)
\end{pspicture}
\end{LTXexample}
\begin{LTXexample}[morekeywords={[21]{wire}}]
\begin{pspicture}(3,1.5)
  \elecmixer[wire=b](0,1)(3,1)(1,0)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
% \end{enumerate}
%
%
% \ifENGLISH\subsection{Appearance of automatic connections}\fi
% \ifGERMAN\subsection{Aussehen der automatischen Verbindungen}\fi
% \label{sec:drawconn-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. Eine identisches Vererbungsdiagramm besteht 
% für die entsprechenden \opt{Wire\ldots} Stile.}%
% \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. An identical inheritance tree applies to the respective 
% \opt{Wire\ldots} styles.}%
% \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{sty:FiberIn}%
% \xLstyle{FiberIn1}\label{sty:FiberIn1}%
% \xLstyle{FiberIn2}\label{sty:FiberIn2}%
% \xLstyle{FiberOut}\label{sty:FiberOut}%
% \xLstyle{FiberOut1}\label{sty:FiberOut1}%
% \xLstyle{FiberOut2}\label{sty: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 use the
% styles \Lstyle{FiberIn1} and \Lstyle{FiberIn2} which inherit from
% \Lstyle{FiberIn}. All output fibers use the style \Lstyle{FiberOut}, in case of two output fibers they use 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{WireIn}\\
%     \opt{WireIn1}\\
%     \opt{WireIn2}\\
%     \opt{WireOut}\\
%     \opt{WireOut1}\\
%     \opt{WireOut2}
%   \end{tabular}}%
% ]%
% \ifENGLISH
% Style \Lstyle{WireIn} applies to all input wires, it inherits from
% \Lstyle{Wire}. If the component has more than one input wire they use
% the styles \Lstyle{WireIn1} and \Lstyle{WireIn2} which inherit from
% \Lstyle{WireIn}. All output wires use the style \Lstyle{WireOut}, in
% case of two output wires they use the styles \Lstyle{WireOut1} and
% \Lstyle{WireOut2} which inherit from \Lstyle{WireOut}. 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{WireIn} bezieht sich auf alle eingehenden
% elektrischen Verbindungen und erbt alle Eigenschaften von
% \Lstyle{Wire}. Hat eine Komponente zwei davon, so können diese mit
% \Lstyle{WireIn1} und \Lstyle{WireIn2} angesprochen werden, die alles
% von \Lstyle{WireIn} übernehmen. Entsprechend bezieht sich
% \Lstyle{WireOut} auf alle ausgehenden elektrischen Verbindungen, falls
% es davon zwei gibt dann können diese mit \Lstyle{WireOut1} und
% \Lstyle{WireOut2} geändert werden. Siehe \prettyref{fig:fiberstyles}
% für ein Vererbungsdiagramm der Stile. 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
% \xLstyle{WireIn}\label{sty:WireIn}%
% \xLstyle{WireIn1}\label{sty:WireIn1}%
% \xLstyle{WireIn2}\label{sty:WireIn2}%
% \xLstyle{WireOut}\label{sty:WireOut}%
% \xLstyle{WireOut1}\label{sty:WireOut1}%
% \xLstyle{WireOut2}\label{sty:WireOut2}%
%
% \item[\smash{\begin{tabular}[t]{@{}r@{}}%
%   \opt{new}\prm{style}\\
%   \opt{addto}\prm{style}
%   \end{tabular}}]
%   \xLkeyword{newFiberIn}\xLkeyword{addtoFiberIn}%
%   \label{prm:newFiberIn}\label{prm:addtoFiberIn}
%   \xLkeyword{newFiberIn1}\xLkeyword{addtoFiberIn1}
%   \label{prm:newFiberIn1}\label{prm:addtoFiberIn1}
%   \xLkeyword{newFiberIn2}\xLkeyword{addtoFiberIn2}
%   \label{prm:newFiberIn2}\label{prm:addtoFiberIn2}
%   \xLkeyword{newFiberOut}\xLkeyword{addtoFiberOut}
%   \label{prm:newFiberOut}\label{prm:addtoFiberOut}
%   \xLkeyword{newFiberOut1}\xLkeyword{addtoFiberOut1}
%   \label{prm:newFiberOut1}\label{prm:addtoFiberOut1}
%   \xLkeyword{newFiberOut2}\xLkeyword{addtoFiberOut2} 
%   \label{prm:newFiberOut2}\label{prm:addtoFiberOut2}
%   \xLkeyword{newWireIn}\xLkeyword{addtoWireIn}
%   \label{prm:newWireIn}\label{prm:addtoWireIn}
%   \xLkeyword{newWireIn1}\xLkeyword{addtoWireIn1}
%   \label{prm:newWireIn1}\label{prm:addtoWireIn1}
%   \xLkeyword{newWireIn2}\xLkeyword{addtoWireIn2}
%   \label{prm:newWireIn2}\label{prm:addtoWireIn2}
%   \xLkeyword{newWireOut}\xLkeyword{addtoWireOut}
%   \label{prm:newWireOut}\label{prm:addtoWireOut}
%   \xLkeyword{newWireOut1}\xLkeyword{addtoWireOut1}
%   \label{prm:newWireOut1}\label{prm:addtoWireOut1}
%   \xLkeyword{newWireOut2}\xLkeyword{addtoWireOut2} 
%   \label{prm:newWireOut2}\label{prm:addtoWireOut2}
%   \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 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 Verbindungen 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\subsection{Bekannte Einschränkungen}\fi
% \ifENGLISH\subsection{Known limitations}\fi
%
% \ifGERMAN Die Kombination von \Lkeyword{fiber} und \Lkeyword{wire}
% erlaubt in der derzeitigen Implementierung (Version \fileversion)
% nicht die beliebige Kombination aller Parametervarianten. Die meisten
% funktionieren, aber das folgende Beispiel zeigt eine Variante, die
% nicht korrekt funktioniert (der \Lcomp{elecsynthesizer} sollte eine
% Eingangsfaser haben):
% \fi
% \ifENGLISH The combination of \Lkeyword{fiber} and \Lkeyword{wire}
% does not allow any arbitrary combination of all parameter values in
% the current implementation (version \fileversion). Most combinations
% do work, but the following examples shows a variant, which does not
% work correctly (the \Lcomp{elecsynthesizer} should have an input fiber):
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{fiber, wire}}]
\begin{pspicture}(3,3)
  \psset[optexp]{fiber=i, wire=+i}
  \fiberdelayline(0,2.5)(3,2.5)
  \optbox(0,1.5)(3,1.5)
  \elecsynthesizer[position=0.5](0,0.5)(3,0.5)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN In solchen speziellen Fällen muss auf manuelle Verbindungen
% zurückgegriffen werden.
% \fi
% \ifENGLISH In such special cases one must resort to manual
% connections.
% \fi
%
% \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}
%    \xLdipole{optdipole}%
%    \compitem{optdipole}[options](in)(out){comp}{label}
% \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
% 
% \xLdipole{opttripole}%
% \compitem{opttripole}[options](in)(center)(out){comp}{label}
%
% \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. \Lcomp{opttripole} defines a
% single reflective interface, whereas \Lcomp{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. \Lcomp{opttripole} definiert eine einzelne reflektive
% Grenzfläche, \Lcomp{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
%   \Lcomp{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
%   \Lcomp{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)
\pnodes(0,1){A}(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)
\pnodes(0,1){A}(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
% 
% \optitem{optdipolecomp}{\prm{macros}}
% \ifGERMAN Mit dieser Option kann die Zeichnung einer Komponente
% definiert werden, um dann mit \Lcs*{newpsobject} basierend auf
% \Lcomp{optdipole} eine neuen Komponente zu definieren.
% \fi
% \ifENGLISH
% This option defines the drawing of a component, and can be used to
% define a new component based in \Lcomp{optdipole} with
% \Lcs*{newpsobject}.
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]optdipolecomp}]
\begin{pspicture}(3,2)
\def\phasemodulatorcomp{%
  \psframe(-1,-0.4)(1,0.4)
  \psframe[fillstyle=hlines](-1.3,-0.5)(1.3,-0.4)
  \psframe[fillstyle=hlines](-1.3,0.5)(1.3,0.4)}
\newpsobject{phasemodulator}{optdipole}{optdipolesize=2 0.8, optdipolecomp={\phasemodulatorcomp}}
\pnodes(0,1){A}(3,1){B}
\phasemodulator(A)(B){LiNbO$_3$}
\drawwidebeam[beamwidth=0.3, beaminside=false](A){}(B)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \optitem{opttripolecomp}{\prm{macros}}
% \ifGERMAN Mit dieser Option kann die Zeichnung einer Komponente
% definiert werden, um dann mit \Lcs*{newpsobject} basierend auf
% \Lcomp{opttripole} eine neuen Komponente zu definieren.
% \fi
% \ifENGLISH
% This option defines the drawing of a component, and can be used to
% define a new component based in \Lcomp{opttripole} with
% \Lcs*{newpsobject}.
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]opttripolecomp}]
\begin{pspicture}(3,2)
\def\ampmodcomp{%
  \psframe*[linestyle=none](-0.5,0)(0.5,0.1)
  \psframe*[linestyle=none, linecolor=gray](-0.5,0.1)(0.5,0.2)}
\newpsobject{ampmod}{opttripole}{opttripolecomp={\ampmodcomp}}
\pnodes(0,0){A}(2,1.5){B}(3,0){C}
\ampmod(A)(B)(C){AM}
\drawwidebeam[beamwidth=0.3](A){}(C)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \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}
  \pnodes(0,1){A}(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 since version 3.0. Some parts may
% be subject to change which are not backward compatible.
% \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 seit Version 3.0 werden
% grob beschrieben, können sich aber noch ändern und sind nicht zwangsläufig
% abwärtskompatibel.
% \fi
%
% \begin{ltxsyntax}
%   \xLcs{newOptexpDipole}\cmditem{newOptexpDipole}[fixopt]{name}{dftopt}
%   \xLcs{newOptexpTripole}\cmditem{newOptexpTripole}[fixopt]{name}{dftopt}
%   \xLcs{newOptexpFiberDipole}\cmditem{newOptexpFiberDipole}[fixopt]{name}{dftopt}
%   \xLcs{newOptexpElecDipole}\cmditem{newOptexpElecDipole}[fixopt]{name}{dftopt}
% \end{ltxsyntax}
%
% \ifENGLISH 
% These macros generate all organizing code for the component
% \textbackslash\prm{name} 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. 
%
% With the argument \prm{fixopt} you can specify argument settings which
% will not be allowed to be overwritten, with \prm{dftopt} you can
% specify a set of default arguments which may be overwritten with the
% components optional argument. Both arguments \prm{fixopt} and
% \prm{dftopt} are optional and may be omitted.
%
% The macros \Lcs{newOptexpFiberDipole} and \Lcs{newOptexpElecDipole}
% only differ from the generic \Lcs{newOptexpDipole} in the connection
% settings, like the components in \prettyref{chap:fibercomp} and
% \prettyref{chap:electrcomp}, respectively.
%
% 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 (optional)
% \item Optional support for \Lkeyword{rotateref}, \Lkeyword{extnode} and
%   \Lkeyword{position}\opt{=start|end} (optional).
% \end{enumerate}
% \fi
% \ifGERMAN
% Diese Makros erzeugen den Code für die Positionierung, Drehung,
% Beschriftung und die Ebenenverwaltung der neuen Komponente
% \textbackslash\prm{name}. Im einfachsten Fall müssen Sie lediglich die
% eigentliche Zeichnung der Komponente erstellen.
%
% Mit dem Argument \prm{fixopt} können Optionen voreingestellt werden,
% die später über das optionale Argument der Komponente nicht verändert
% werden können, \prm{dftopt} erlaubt Voreinstellungen zu machen, die
% überschrieben werden können. Beide Argumente \prm{fixopt} und
% \prm{dftopt} sind optional und können auch ganz weggelassen werden.
%
% 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 (optional).
% \item Unterstützung für \Lkeyword{rotateref}, \Lkeyword{extnode} und
%   \Lkeyword{position}\opt{=start|end} (optional).
% \end{enumerate}
% \fi
%
% \ifGERMAN Die folgenden Abschnitte enthalten die Entwicklung einer
% einfachen Beispielkomponente \nxLcs{testcomp}.
% \fi
% \ifENGLISH The following section show the development of a simple
% example component \nxLcs{testcomp}.
% \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}
\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}
\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 Unsere Beispielkomponente und ihre Zeichnung wird also wie
% folgt definiert:
% \fi 
% \ifENGLISH Our example component and its drawing are defined as
% follows:
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{testcomp@comp}}]
\begin{pspicture}(3, 2)
\newOptexpDipole{testcomp}
\makeatletter
\def\testcomp@comp{%
  \psframe[fillstyle=solid, fillcolor=black!30](-0.5,-0.5)(-0.3,0.5)
  \psframe(-0.5,-0.5)(0.5,0.5)
}%
\makeatother
\begin{optexp}
\testcomp[position=0.6, labelalign=l](0,1)(3,1){label}
\drawbeam[beaminside=false](0,1){}(3,1)
\end{optexp}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN Die Positionierung der Komponente und der Beschriftung,
% sowie die Ebenen funktioniert also schon.
% \fi
% \ifENGLISH The positioning of the component and the label, and the
% layering is working already.
% \fi
%
% \ifENGLISH\subsection{Support for raytracing}\fi
% \ifGERMAN\subsection{Unterstützung von Raytracing}\fi
%
% \ifGERMAN Damit die Komponente Raytracing unterstützt, müssen die
% Grenzflächen mit ihren Eigenschaften definiert werden. Die Definition
% der Ebenen werden in einenm Makro \nxLcs{\prm{name}@nodes} definiert,
% damit sie auch in den unterschiedlichen Ebenen verfügbar sind.
%
% Die Definition der Ebenen erfolgt dann über das Makro \Lcs*{newOptexpComp}
%
% \begin{lstlisting}[gobble=2]
% \def\testcomp@nodes{%
%   \newOptexpComp{%
%     % Definition der ersten Grenzflaeche (GF)
%     {-0.5 0} % x- und y-Koordinate der GF-Mitte
%     {0 1}    % Richtungsvektor der GF (x und y)
%     -0.5 0.5 % Grenzen fuer die NA, gesehen als Faktoren des GF-Vektor
%     trans    % Verhalten der GF, kann 'trans', 'refl' oder 'abs' sein
%     {PlainIfc} % Art der GF
%     % Dasselbe fuer die rechte GF, nur die Mitte ist anders
%     {0.5 0} {0 1} -0.5 0.5 trans {PlainIfc}
%     \POE@key@n % Brechungsindex, koennte jede Zahl sein
%   }%
% }%
% \end{lstlisting}
% \fi
% \ifENGLISH To add support for ray-tracing, you must define the
% interface with their properties. The definitions are nested in a macro
% \nxLcs{\prm{name}@nodes} in order to be accessible in the different
% layers.
%
% The definitions are done with the macro \Lcs*{newOptexpComp}
%
% \begin{lstlisting}[gobble=2]
% \def\testcomp@nodes{%
%   \newOptexpComp{%
%     % definition of the first interface (IF)
%     {-0.5 0} % x- and y-coordinate of the IF center
%     {0 1}    % direction vector of the IF (x and y)
%     -0.5 0.5 % limits use for the NA as factor for IF vector.
%     trans    % behavior of the IF, can be 'trans', 'refl' or 'abs'
%     {PlainIfc} % type of IF
%     % the same for the right IF, only the center is different
%     {0.5 0} {0 1} -0.5 0.5 trans {PlainIfc}
%     \POE@key@n % refractive index, could be any number
%   }%
% }%
% \end{lstlisting}
% \fi
%
% \ifENGLISH So, in condensed form, our example component looks like
% this, and the beam is not drawn inside the component any more:
% \fi
% \ifGERMAN Unsere Komponent sieht also folgendermaßen aus, und der
% Strahl verläuft nicht mehr innerhalb der Komponente:
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{testcomp@comp, testcomp@nodes}}]
\begin{pspicture}(3, 2)
\newOptexpDipole{testcomp}
\makeatletter
\def\testcomp@comp{%
  \psframe[fillstyle=solid, fillcolor=black!30](-0.5,-0.5)(-0.3,0.5)
  \psframe(-0.5,-0.5)(0.5,0.5)}%
\def\testcomp@nodes{%
  \newOptexpComp{%
    {-0.5 0} {0 1} -0.5 0.5 trans {PlainIfc}
    {0.5 0} {0 1} -0.5 0.5 trans {PlainIfc} \POE@key@n }}%
\makeatother
\begin{optexp}
\testcomp[position=0.6, labelalign=l](0,1)(3,1){label}
\drawbeam[beaminside=false](0,1){}(3,1)
\end{optexp}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifENGLISH\subsection{Support for external nodes}\fi
% \ifGERMAN\subsection{Unterstützung von externen Knoten}\fi
%
% \ifGERMAN Damit nun, als letzter Schritt auch externe Knoten mit \Lkeyword{extnode},
% Positionierung an den Anfang oder das Ende mit
% \Lkeyword{position}\opt{=start|end}, oder auch das Setzen eines
% anderen Drehpunktes mit \Lkeyword{rotateref} möglich wird, müssen die
% externen Dimensionen der Komponente bekannt gemacht werden. Dafür muss
% ein weiteres Makro mit dem Name \nxLcs{\prm{name}@ref} definiert
% werden, in dem auf Postscript-Ebene die Werte \opt{@@x} (halbe
% Breite), \opt{@@y} (halbe Höhe), und optional auch \opt{@@x0} und
% \opt{@@y0} (Verschiebung der Mitte) definiert werden müssen.
% \fi
% \ifENGLISH To enable, as last step, support for external nodes with
% \Lkeyword{extnode}, positioning at the start or end with
% \Lkeyword{position}\opt{=start|end}, and setting the rotation
% reference node with \Lkeyword{rotateref}, we need to provide the
% external dimensions of the component. For this we need to define a new
% macro \nxLcs{\prm{name}@ref}, which defines at Postscript level the
% values \opt{@@x} (half width), \opt{@@y} (half height), and optionally
% \opt{@@x0} and \opt{@@y0} (offset of the center). 
% \fi
% \begin{lstlisting}[gobble=2]
% \def\testcomp@ref{%
%   \POE@setref{ /@@x 0.5 def /@@y 0.5 def }%
% }%
% \end{lstlisting}
%
% \ifGERMAN Der Code für unsere Beispielkomponente \nxLcs{testcomp} ist
% damit vollständig, und sieht folgendermaßen aus:
% \fi
% \ifENGLISH This completes the code for our example component
% \nxLcs{testcomp}, which now looks like this:
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]{testcomp@comp, testcomp@nodes, testcomp@ref}}]
\begin{pspicture}(3, 2)
\newOptexpDipole{testcomp}
\makeatletter
\def\testcomp@comp{%
  \psframe[fillstyle=solid, fillcolor=black!30](-0.5,-0.5)(-0.3,0.5)
  \psframe(-0.5,-0.5)(0.5,0.5)}%
\def\testcomp@nodes{%
  \newOptexpComp{%
    {-0.5 0} {0 1} -0.5 0.5 trans {PlainIfc}
    {0.5 0} {0 1} -0.5 0.5 trans {PlainIfc} \POE@key@n }}%
\def\testcomp@ref{%
  \POE@setref{ /@@x 0.5 def /@@y 0.5 def }}%
\makeatother
\begin{optexp}
\testcomp[position=0.6, labelalign=l, extnode=tl](0,1)(3,1){label}
\drawbeam[beaminside=false](0,1){}(3,1)
\psdot(\oenodeExt{})
\end{optexp}
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \ifGERMAN
%   \subsection{Beispiele für benutzerdefinierte Komponenten}
% \fi
% \ifENGLISH
%   \subsection{Examples of custom components}
% \fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(6,4)
  \newOptexpTripole{raindrop}
  \makeatletter
  \def\raindrop@nodes{%
    \newOptexpComp{%
      {0 -2} { 0 2 } -2 2 trans {CurvedIfc}
      {0 2} {0 -2} -2 2 refl {CurvedIfc}
      {0 -2} { 0 2 } -2 2 trans {CurvedIfc}
      \POE@key@n }}%
  \def\raindrop@comp{\pscircle(0,0){2}}%
  \raindrop(0,4)(4,2)(0,0)
  \psset{beamalign=abs, arrows=->, arrowscale=2}
  \drawbeam[linecolor=red](0,3){}(0,1)
  \drawbeam[n=*n*1.05, linecolor=blue](0,3){}(0,1)
\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}
  \pnodes(2,4){L}([Xnodesep=4]L){M}([Xnodesep=1.5]M){IRSpec}([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, 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)
\pnodes(-2,0){LOut}(0,0){Grat}(4;45){Out}(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)
\pnodes(1.4,1.3){Laser}(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)
\pnodes(1.2,1){Start}(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)
\pnodes(1.2,1){Start}(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{2.5cm}
\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)
\pnodes(2,7){L}(2,5.8){Pbs}([Xnodesep=1]Pbs){Blk1}(2,2.3){Bs}
\pnodes([Xnodesep=-1]Bs){Blk2}([Xnodesep=3.5]Bs){Out}(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}
\pnodes(2.3,2.3){Lin}([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=-0.5,offset=-1]\oenodeExt{L}){Osc}
\elecsynthesizer[wire=none](Osc)(\oenodeExt{EAM}|Osc){10\,GHz}
\optarrowcomp[arrowcompsize=0.8 0.6, arrowscale=1.5](Osc)(\oenodeExt{EAM}|Osc){$\tau$}
\drawfiber{1-4}
\addtopsstyle{Wire}{arrows=->, arrowinset=0, arrowscale=1.5}
\drawwire{5}{6}\psset[optexp]{wireangleB=90}
\drawwire{6}(\oenodeExt{EAM})\drawwire{5}(\oenodeExt{L})
\end{pspicture}
\end{LTXexample}

\enlargethispage{1cm}
\begin{LTXexample}[pos=t, caption={caption}]
\begin{pspicture}(0.2,0.6)(8.2,3.5)
\pnodes(2,3){Laser}(2,1){PwMeter}(6,3){CplTop}(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}
\pnodes(2,5){PC1in}(4,5){PC1out}(6,5){PC2in}(8,5){PC2out}(2,2){CplSig}
\pnodes(5,2){CplIn}(2,1){CplOut}(10,4.5){Pump}(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)
\pnodes(1,4){SigIn}(3,4){BS}(3,5){LO}(5,4){Det1}(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}
\pnodes(2.4,1){BS1}([offset=3]BS1){M1}([Xnodesep=5.5]M1){PP}(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)
\pnodes(1.5,5){Laser}(4,5){PBS}(6.5,5){PBS2}(6.5,5.7){piezo}(4,2){BSFwd}
\pnodes(6.5,2){BSBwd}(2,2){BS4f}(2,0.5){M4f3}(8,2){M4f1}(8,0.5){M4f2}(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, linejoin=2}
\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{optboxwidth=1, labelstyle=\footnotesize, fiber=none}
\pnodes(1,5){LD}([Xnodesep=5.5]LD){CPLin1}([offset=-2]CPLin1){CPLin2}
\pnodes([Xnodesep=2.5]CPLin1){CPLout1}([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-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-10}
\pnodes([Xnodesep=-0.5]LD|CPLin2){TL}(RX|TL){TR}([offset=-2.5]TR){BR}(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-16}\drawfiber{17-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}
  \pnodes(1.6,2){In}(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)
  \pnodes(0,1){A}(1,1){BS}(2,1){G}(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}
\pnodes(0,3){A}(8,3){B}(3,1.5){C}(8,0){D}(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}]
\psset{unit=1.5}
\begin{pspicture}(0,1)(2.2,4.2)
  \pnodes(0,2){In}(1,2){G}(1,4){M1}(2,2){M2}(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.5}
  \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}
  \pnodes(2,1){Laser}(12,2){Film}(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}{c}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}
  \pnodes(0,2){In}(1,2){BS}(1,0.5){M1}(2,1){M2}(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, polsize=1}
  \newpsobject{parpol}{polarization}{poltype=parallel, linecolor=red, polsize=0.8}
  \newpsstyle{Polarization}{arrowinset=0, arrowscale=1.2}
  \pnodes(0,1){A}(8,1){B}(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, arrows=->](A){1}{3}
  \parpol[abspos=1](A)(B)\perppol[abspos=1](A)(B)
  \nodexn{(\oenodeBeam{})-1.5(!\oeBeamVec{})}{D}
  \perppol[abspos=7](A)(B)\parpol(D)(\oenodeBeam{})
\end{pspicture}
\end{LTXexample}
\enlargethispage{1.5cm}
\begin{LTXexample}[pos=t, caption={caption}]
\begin{pspicture}(13.7,2.9)
\newpsstyle{Wire}{arm=0.1, arrows=->}
\psset[optexp]{optboxsize=1.2 0.8, optmzmsize=1.2 0.8, fiber=none, label=0.7}
\pnodes(2,1){L}([Xnodesep=11]L){A}
\optbox[position=start, optboxwidth=2, label=0](L)(A){DFB-Laser}
\optbox[abspos=1, label=0, compname=Eam, extnode=t](L)(A){EAM}
\optmzm[abspos=4.5, compname=Mzm1, extnode=t](L)(A){MZM}
\optmzm[abspos=6, compname=Mzm2, extnode=t](L)(A){MZM}
\optamp[abspos=9](L)(A){EDFA}
\drawfiber{1-5}\drawfiber[arrows=->]{}(A)
\pnode([offset=1.5]\oenodeExt{Eam}){Osci}
\elecsynthesizer[compname=Syn, position=0.5, wire=o, label=0.5 . r](Osci)(\oenodeExt{Eam}){10\,GHz}
\psset[optexp]{label=0, wire, optboxsize=0.8 1.2}
\optbox[compname=Ppg1](\oenodeExt{Mzm1}|Osci)(\oenodeExt{Mzm1}){PPG}
\optbox[compname=Ppg2](\oenodeExt{Mzm2}|Osci)(\oenodeExt{Mzm2}){PPG}
\drawwire[arrows=-, wireangleB=-90]{Syn}(\oenodeExt{Mzm2}|Osci)
\rput([offset=0.5, Xnodesep=-0.3]A){Faserschleife}
\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, label=0, fiber=none}
\pnodes(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}
\optbox[position=start](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-5}
\optbox[position=start, compname=S, extnode=b](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-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, compname=Pd, extnode=t](Cpl)(PD){PD}
\optbox[position=end, compshift=-1.5](Cpl)(PD){OSA}
\optamp[fiber](Pump)(\oenodeIfc{2}{13})
\optbox[position=start, optboxsize=0.6 1.2](Pump)(Pump|Cpl){Pump}
\drawfiber{10-15}\drawfiber{14}{16}
\optbox[compshift=0.7, optboxsize=2.5 0.8](\oenodeExt{M2})(\oenodeExt{Pd}|\oenodeExt{M2}){Lock-In Amp}
\addtopsstyle{Wire}{arm=0.1}
\drawwire[wireangleA=90, linearc=0.3](\oenodeExt{M2}){}
\drawwire[wireangleB=90, linearc=0.3]{}(\oenodeExt{Pd})
\elecsynthesizer([offset=0.2]\oenodeExt{M1})(\oenodeExt{M1})
\psset[optexp]{synthshape=rectangle}
\elecsynthesizer[synthtype=sawtooth](\oenodeExt{S}|Pump)(\oenodeExt{S})
\elecsynthesizer[synthtype=triangle](\oenodeExt{M3}|Pump)(\oenodeExt{M3})
\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}
\pnodes(2.3,0){In}([offset=0.5]In){STM1}([Xnodesep=-2]STM1){M1}
\pnodes([offset=1]M1){M2}([offset=2]STM1){M3}([Xnodesep=-1]M3){M4}(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, caption={caption}]
\begin{pspicture}(13.8,3.8)
  \pnode(2.3,2){Signal}
  \pnode([Xnodesep=1.5,offset=0.8]Signal){UpIn}
  \pnode([Xnodesep=1.5, offset=-0.8]Signal){LowIn}
  \pnode([Xnodesep=3.5]UpIn){UpOut}
  \pnode(UpOut|LowIn){LowOut}
  \pnode([Xnodesep=1.5]UpOut){UpIn2}
  \pnode([Xnodesep=3]UpIn2){UpOut2}
  \pnode([Xnodesep=1.5]LowOut){LowIn2}
  \pnode(UpOut2|LowIn2){LowOut2}
  \psset{labelstyle=\footnotesize}
  \psset{fiber=none}\addtopsstyle{Fiber}{linecolor=red}
  \psset{wire=none}\addtopsstyle{Wire}{arm=0.1, arrows=->}
  \optbox[position=start, label=0, optboxsize=2.3 0.8](Signal)([Xnodesep=0.1]Signal){2.5\,ps, 10\,GHz}
  \wdmsplitter[label=0.4](Signal)(UpIn)(LowIn){50\%}
  \optfiber[fiberloops=4, label=0.4, position=0.3](LowIn)(LowOut){L$_2$}
  \optswitch[position=0.7](LowIn)(LowOut){AOM}
  \optfiber[fiberloops=2, label=0.4, position=0.2](UpIn)(UpOut){L$_1$}
  \optswitch[position=0.7](UpIn)(UpOut)
  \optcoupler[label=0.4, position=0.3](UpOut)(LowOut)(UpIn2)(LowIn2){50\%}
  \optbox[optboxsize=2 0.8, position=end, label=0, extnode=t](LowIn2)(LowOut2){Messsystem}
  \drawfiber{1-4}{7}(LowIn2)\drawfiber[arrows=->](LowIn2){8}
  \optdetector[abspos=0.4, detsize=0.6 0.8](UpIn2)(UpOut2){PD}
  \optbox[optboxsize=0.8 0.8, label=0, position=0.44](UpIn2)(UpOut2){$\div 8$}
  \optamp[position=0.8](UpIn2)(UpOut2)
  \optbox[position=end, extnode=b, label=0, optboxsize=2 0.8](UpIn2)(UpOut2){Faserkamm}
  \drawfiber{2}{5-7}(UpIn2)\drawfiber[arrows=->](UpIn2){9}
  \drawwire{9-12}
  \drawfiber[arrows=->](\oenodeExt{12})(\oenodeExt{8})
\end{pspicture}
\end{LTXexample}

\begingroup
\captionsetup[lstlisting]{format=poecaption}
\begin{LTXexample}[pos=t, caption={\ifGERMAN Angepasst von \fi\ifENGLISH Adapted from \fi\doiurl{10.1103/PhysRevLett.105.263904}}, label={ex:wgm-pdc}]
\begin{pspicture}(0.6,2.8)(6.8,7.8)
\pnodes(1,6){Laser}(1,5){M}(3,4){PR}(5,5){PT}(6,7){D1}
\newpsstyle{Glass}{fillcolor=blue, fillstyle=solid, opacity=0.15, linecolor=blue!30!white}
\begin{optexp}
  \optbox[position=start, innerlabel, optboxwidth=1.8](Laser)(M){Nd:YAG}
  \optprism[style=Glass, compname=P, n=1, prismtype=reflective, prismangle=60, labeloffset=1.2](M)(PR)(PT){\begin{tabular}{@{}c@{}}diamond\\ prism\end{tabular}}
  \mirror(Laser)(M)(\oenodeIfc{2}{P})%
  \lens[abspos=1.05, style=Glass](\oenodeIfc{2}{P})(M)%
  \optprism[compname=PDet, style=Glass](\oenodeIfc{2}{P})(PT)(D1)%
  \lens[abspos=1.05, style=Glass](\oenodeIfc{2}{P})(\oenodeOut{PDet})%
  \newpsstyle{Beam}{linestyle=none, fillstyle=solid}%
  \drawwidebeam[fillcolor=green, beamwidth=0.2, beaminsidelast, beampathcount=5]{1}{3}{4}{2}%
  \drawwidebeam[fillcolor=orange, beaminsidefirst, startinsidecount=1, loadbeam, beaminsidelast]{2}{6}%
  \psset{savebeam=false, loadbeam, beamnodealign=vector}%
  \drawwidebeam[fillcolor=orange]{6}{5}%
  \drawwidebeam[fillcolor=green, n=1.2, beampathskip=1, savebeam=2]{6}{5}(D1)
  \drawwidebeam[fillcolor=red, beampathskip=1, n=1.4, savebeam=3]{6}{5}(D1)
  \drawwidebeam[fillcolor=red!50!black, beampathskip=1, n=1.57, savebeam=4]{6}{5}(D1)
  \multido{\i=2+1}{3}{%
    \backlayer{%
      \pnode(!\oeBeamCenter{\i}){Det\i}
      \nodexn{(Det\i)-(!\oeBeamVecMedian{\i})}{Det\i'}}
    \optdetector[detsize=0.6 0.5](Det\i')(Det\i)}
\end{optexp}
\pscircle[style=Glass]([offset=-0.5]\oenodeIfc{2}{P}){0.5}
\rput[l]([offset=-0.5,Xnodesep=0.7]\oenodeIfc{2}{P}){WGM}
\end{pspicture}
\end{LTXexample}
\endgroup

\begin{LTXexample}[caption={caption}]
\begin{pspicture}(2.2,2.2)
\definecolor[ps]{bl}{rgb}{tx@addDict begin Red Green Blue end}%
\pnode(0,0.5){In}\pnode(2,0.5){G1}
\pnode([Xnodesep=-1.5, offset=1.3]G1){G2}\pnode(G1|G2){MG}
\begin{optexp}
  \optgrating[angle=40, gratingalign=c](In)(G1)(G2)
  \optgrating[reverse, angle=40, gratingalign=c](G1)(G2)(MG)
  \mirror[mirrorwidth=1, mirrortype=extended](G2)(MG)(G2)
  \drawbeam[linecolor=red](In){1}
  \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]{1-2}%
    \drawbeam[linecolor=bl, loadbeampoints]{2-3}
  }%
\end{optexp}
\end{pspicture}
\end{LTXexample}

\begin{LTXexample}[pos=t, caption={caption}]
\begin{pspicture}(5.6,3)
\pnodes(0,0.5){S1}(2,2.5){S2}(3,1.5){S3}(4,0.5){S4}(4.5,1){S5}
\psset{prismangle=30, mirrortype=extended}
\definecolor[ps]{bl}{rgb}{tx@addDict begin Red Green Blue end}%
\begin{optexp}
  \optprism(S1)(S2)(S3)\optprism(S3)(S4)(S5)
  \mirror[compshift=-0.07](\oenodeIn{2})([offset=1,Xnodesep=1]\oenodeIn{2})(\oenodeIn{2})
  \drawbeam[linecolor=orange, ArrowInside=->, ArrowInsidePos=0.2, arrowscale=1.5](S1){1}
  \addtopsstyle{Beam}{linecolor=bl, linewidth=0.35\pslinewidth, beampathskip=1}
  \multido{\r=0+0.5}{120}{%
    \pstVerb{\r\space 620 590 sub 59 div mul 590 add 
             tx@addDict begin wavelengthToRGB end }%
    \drawbeam[n=3.42 -0.002 \r\space mul add, beampos=\r\space 60 sub 0.0002 mul](S1){1-3}
  }%
\end{optexp}
\end{pspicture}
\end{LTXexample}

\begin{LTXexample}[pos=t, caption={caption}, label=ex:dsotm]
\begin{pspicture}(3,1.7)
\pnodes(-1,0){A}(1,1){B}(3,0){C}
\psframe*(0,0)(3,1.7)
\begin{optexp}
  \optplane(0,0.7)
  \optprism[prismalign=center, linecolor=white](A)(B)(C)
  \optplane(C)
  \addtopsstyle{Beam}{linecolor=white}
  \drawbeam[ArrowInside=->]{1-2}
  \definecolor[ps]{bl}{rgb}{%
    tx@addDict begin Red Green Blue end}%
  \addtopsstyle{Beam}{linestyle=fade, beaminsidelast, fadeto=black}
  \multido{\i=0+1}{60}{%
    \drawbeam[n=1.5 \i\space 0.003 mul add, linecolor=white, beampathskip=1, fadefuncname=gauss]{1-2}
    \pstVerb{\i\space 650 400 sub 59 div mul 400 add 
      tx@addDict begin wavelengthToRGB end }%
    \drawbeam[n=1.5 \i\space 0.003 mul add, linecolor=bl, beampathskip=2, linewidth=0.3\pslinewidth]{-}%
  }%
\end{optexp}   
\end{pspicture}  
\end{LTXexample}

\begin{LTXexample}[pos=t, caption={\ifENGLISH Adapted from \fi\ifGERMAN Angepasst von \fi\href{https://tex.stackexchange.com/q/581952}}, label=ex:multi-input-coupler]
\begin{pspicture}(10,6)
  \begin{optexp}
    \psset[optexp]{usefiberstyle, couplersize=0.25, couplersep=0.07}
    \newpsstyle{Fiber}{linecolor=orange, linewidth=2\pslinewidth}
    \pnodes(2,1){PumpDiode}(2,5){UpperPumpDiode}(1,3){SignalIsolatorIn}(4, 3){SignalIsolatorOut}(1,3){SignalIn}(10,3){SignalCombinerOut}
    \pnodes(7,3){FiberIn}(9,3){FiberOut}(9,3){AmpOut}
    \optdiode[compname=PumpDiode, position=start](PumpDiode)([Xnodesep=1]PumpDiode){Pump diode}
    \optdiode[compname=UpperPumpDiode, position=start](UpperPumpDiode)([Xnodesep=1]UpperPumpDiode){Pump diode}
    \optisolator[compname=SignalIsolator, fiber=none](SignalIsolatorIn)(SignalIsolatorOut)%
        {\begin{tabular}{@{}c@{}}Signal\\Isolator\end{tabular}}
    \wdmcoupler[compname=SignalPumpCombiner](UpperPumpDiode)(\oenodeOut{SignalIsolator})(PumpDiode)(FiberIn)%
        {\begin{tabular}{@{}c@{}}Signal/Pump\\light combiner\end{tabular}}
    \optfiber[
        compname=ActiveFiber,
        position=start,
        addtoFiberOut={arrows=->}](FiberIn)(FiberOut)%
        {\begin{tabular}{@{}c@{}}Active\\fiber\end{tabular}}
    \drawfiber[ArrowInside=->](SignalIn){SignalIsolator}
  \end{optexp}
  \nput{75}{AmpOut}{\begin{tabular}{@{}c@{}}Amplifier\\Output\end{tabular}}
  \nput{-90}{SignalIn}{\begin{tabular}{@{}c@{}}Signal\\Input\end{tabular}}         
\end{pspicture}
\end{LTXexample}

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

\psset{unit=1.1, usefiberstyle=false}
\begin{pspicture}(9.3,6.1)
  \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.7){LD}\pnode([Xnodesep=3.2]LD){LoopIn}\pnode([offset=-1.2]LoopIn){LoopInsIn}
  \pnode([Xnodesep=2]LoopInsIn){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.6 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-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}
  \pnode([offset=1.2, Xnodesep=-0.7]\oenodeExt{Mod}){Osci}\pnode(\oenodeExt{PM}|Osci){Tmp}
  \psset{wire=none, fiber=none, label=0.5 180 b}
  \elecsynthesizer(Osci)(Tmp){SYN}
  \elecsynthesizer[synthshape=rectangle, synthtype=pulse, abspos=0.7, compname=Pg, extnode=b](Osci)(Tmp){PG}
  \optfilter[abspos=2](Osci)(Tmp){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}}
  \drawwire[arm=0]{12-14}\drawwire[wireangleB=-90, arrows=->]{14}(\oenodeExt{PM})
  \psline[style=Wire, arrows=->](\oenodeExt{Pg})(\oenodeExt{Mod})
  \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}}, label={ex:ratchet}]

\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

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

\begin{pspicture}(-0.5,-0.4)(13,11)
\psset{%
  optboxsize=0.8 0.6, 
  arrowcompsize=0.8 0.5,
  optmzmsize=0.8 0.6,
  isolatorsize=0.8 0.5,
  filtersize=0.6,
  detsize=0.5 0.6,
  fiber=none, wire=none,
  usefiberstyle=false,
  labeloffset=0.5, labelstyle=\footnotesize
}
\footnotesize
\newpsobject{elecfilter}{optfilter}{usewirestyle}
\addtopsstyle{Wire}{arrowscale=1.2, arrows=->, linewidth=1.5\pslinewidth}
\newpsstyle{FiberComp}{linecolor=red!80!black}
\newpsstyle{Fiber}{style=FiberComp, arrows=->, linewidth=1.5\pslinewidth}
  \pnode(1,10){Syn}\pnode([Xnodesep=8]Syn){Pm}
  \elecsynthesizer[compname=Syn, labelalign=t](Syn)(Pm){10\,GHz}
  \fiberdelayline[compname=Voa1, abspos=2.5, label= 0.6 . t](Syn)(Pm){VOA}
  \optbox[compname=Am, abspos=4, innerlabel, extnode=b](Syn)(Pm){AM}
  \fiberdelayline[compname=DelayPm, abspos=5.5, label=0.6 . t](Syn)(Pm){DLY}
  \optbox[fiber, addtoFiber={arrows=->}, style=FiberComp, label=0, compname=Pm, extnode=t, optboxheight=0.7]([offset=-1]Pm)([offset=1]Pm){PM}
  \elecsynthesizer[synthtype=rectangle, synthrectwidth=0.3, wire, addtoWire={arrows=->}, label=. -45 l]([offset=-0.5]\oenodeExt{Am})(\oenodeExt{Am}){AWG}
  \pnode([offset=-0.5, Xnodesep=-1]\oenodeIn{Voa1}){A}
  \pnode([offset=-1.5]A){B}
  \eleccoupler[eleccouplertype=directional, eleccouplerinput=right, compname=Cpl](B)(A)
  \pnode([Xnodesep=-1.2]\oenodeIn{}){EamIn}
  \pnode([Xnodesep=0.5,offset=-0.3]\oenodeIfc{2}{}){N1}
  \pnode([offset=-1.3]N1){N2}
  \optisolator[label=0.4 . r, compname=Iso1](N1)(N2){Isolator}
  \optarrowcomp[compname=DelayPpg, labelalign=l]([offset=-1.4]N2)(N2){DLY}
  \fiberbox[position=start, 
            label=0, 
            fiberboxsize=0.7 1, 
            fiberboxcount=2x1,
            fiberboxsepin=0.2, 
            compname=Ppg]([offset=-0.4]\oenodeIn{DelayPpg})(\oenodeIn{DelayPpg}){PPG}
  \pnode([offset=-0.5,Xnodesep=-0.5]\oenodeIn{Ppg}){MzmAmp1}
  \pnode([offset=-0.5,Xnodesep=0.5]\oenodeIfc{2}{Ppg}){MzmAmp2}
  \pnode([offset=-1.5,Xnodesep=-0.9]MzmAmp1){MzmIn}
  \pnode([offset=-1.5,Xnodesep=0.9]MzmAmp2){MzmOut}
  \optamp[abspos=0.5, compname=MzmAmp1](MzmAmp1)(MzmAmp1|MzmIn)
  \optamp[abspos=0.5, compname=MzmAmp2](MzmAmp2)(MzmAmp2|MzmIn)
  \optmzm[abspos=0.9, usefiberstyle, style=FiberComp, compname=Mzm1, extnode=t, labelalign=t](MzmIn)(MzmOut){MZM}
  \optmzm[abspos=2.3, usefiberstyle, style=FiberComp, compname=Mzm2, extnode=t, labelalign=t](MzmIn)(MzmOut){MZM}
  \rput(\oenodeCenter{Ppg}|[offset=-0.2]\oenodeCenter{MzmAmp1}){AMP}
  \pnode([Xnodesep=-1]\oenodeIn{Mzm1}){Eam}
  \optbox[style=FiberComp, 
          label=0, 
          optboxsize=1 0.6, 
          compname=Eam, 
          extnode=t]([Xnodesep=-1]Eam)([Xnodesep=0.8]Eam){EAM}
  \drawfiber[style=FiberComp, arrows=->]([Xnodesep=-1.2]Eam){Eam}{Mzm1}{Mzm2}(MzmOut)
  \pnode([Xnodesep=8]N2){N3}
  \optfilter[abspos=2, label=. 180 b, compname=Bpf1](N2)(N3){\parbox{\widthof{10\,GHz}}{\centering BPF\\[-1pt] 10\,GHz}}
  \makeatletter\edef\mystart{\the\POE@cnt}\makeatother
  \optbox[label=0, 
          abspos=3.2, 
          optboxsize=0.6 0.6](N2)(N3){$\div 8$}
  \makeatletter\edef\mystartb{\the\POE@cnt}\makeatother
  \optamp[abspos=4.7, label=. 180 b](N2)(N3){AMP}
  \optbox[label=0, 
          abspos=6, 
          optboxsize=0.6 0.6, 
          compname=Div5](N2)(N3){$\div 5$}
  \optfilter[abspos=7.3, label=. 180 b](N2)(N3){\parbox{\widthof{250\,MHz}}{\centering BPF\\[-1pt] 250\,MHz}}
  \pnode([offset=-1]N3){N4}
  \pnode([offset=-2.4]N4){Mixer}
  \optamp[abspos=0.4, label=. 0 l global](N4)(Mixer){AMP}
  \optfilter[innercompalign=abs,
             filtertype=lowpass, 
             abspos=1.4, 
             compname=Bpf,
             extnode=t,
             label=. 0 l global](N4)(Mixer){%
    \parbox{\widthof{300\,MHz}}{LPF\\[-1pt]300\,MHz}%
  }
  \pnode([Xnodesep=-4]Mixer){MixerI}
  \pnode([offset=-2.5]Mixer){MixerR}
  \elecmixer[compname=Mixer, elecmixersize=0.7, labelalign=l](Mixer)(MixerR)(MixerI){Mixer}
  \pnode([Xnodesep=-9.8]MixerR){Menlo}
  \optbox[position=start, 
          compname=Lo, 
          innerlabel, 
          style=FiberComp](Menlo)(MixerR){LO}
  \optdetector[extnode=r, 
               labelalign=t,
               compname=Pd](Menlo)([Xnodesep=0.5]Menlo){\parbox{\widthof{2\,GHz}}{\centering PD\\[-1pt]2\,GHz}}
  \optfilter[abspos=1.5, labelalign=t,
             compname=LoBpf](\oenodeExt{Pd})(MixerR){\parbox{\widthof{250\,MHz}}{\centering BPF\\[-1pt]250\,MHz}}
  \optamp[abspos=3, labelalign=t,
          compname=LoAmp](\oenodeExt{Pd})(MixerR){AMP}
  \drawfiber[arrows=->]{Lo}{Pd}
  \drawwire(\oenodeExt{Pd}){LoBpf}{LoAmp}
  \drawwire[stopnode=N]{LoAmp}{Mixer}
  \optfilter[filtertype=lowpass, 
             abspos=1, 
             label=1.1 180 t, 
             compname=LpfP2](MixerI)(\oenodeIfc{2}{Mixer}){%
               \parbox{\widthof{500\,kHz}}{\centering LPF\\[-1pt]500\,kHz}%
  }
  \optfilter[filtertype=lowpass, 
             abspos=2.7, 
             label=1.1 180 t, 
             compname=LpfP1](MixerI)(\oenodeIfc{2}{Mixer}){%
               \parbox{\widthof{10.7\,MHz}}{\centering LPF\\[-1pt]10.7\,MHz}%
  }
  \optbox[compname=T0,
          extnode=b,
          position=start,
          optboxsize=2.2 0.8,
          innerlabel](MixerI)(\oenodeIfc{2}{Mixer}){$T_0$-Messung}
  \drawwire[wirealign=center]{Mixer}{LpfP1}{LpfP2}{}
  \psline[style=Wire](\oenodeExt{T0}|Menlo)(\oenodeExt{T0})
  \uput{0.4}[-60](\oenodeExt{T0}){\rput[l](0,0){Takt}}
  \drawwire[arrows=<-](\oenodeExt{Eam}){Cpl}
  \drawwire{Syn}{Voa1}{Am}{DelayPm}(\oenodeExt{Pm})
  \drawwire{Syn}{Cpl}{Iso1}{DelayPpg}{Ppg}{MzmAmp1}(\oenodeExt{Mzm1})
  \drawwire{Ppg}{MzmAmp2}(\oenodeExt{Mzm2})
  \drawwire{Iso1}{Bpf1}
  \multido{\i=\mystart+1,\ii=\mystartb+1}{7}{%
    \drawwire{\i}{\ii}}
\end{pspicture}
\end{LTXexample}

\begin{LTXexample}[pos=t, caption={caption}]
\begin{pspicture}(10,3)
\makeatletter
\newOptexpTripole{roughsurface}
\def\roughsurface@nodes{%
  \pssavepath[linestyle=none, arrows=-,ArrowInside=-]{\oenode@Path{A}}{%
    \code{0 srand}
    \moveto(!-3 Rand 0.5 sub 0.1 mul)
    \multido{\r=-2.7+0.3}{20}{%
      \lineto(!\r\space Rand 0.5 sub 0.1 mul)}%
  }%
  \newOptexpComp{%
    {0 0} tx@IntersectDict /\PIT@name{\oenode@Path{A}} get 0 0 refl {PathIfc}
    1 }%
}%
\def\roughsurface@comp{%
  \pstracecurve{\oenode@Path{A}}
}%
\makeatother
\optplane[angle=90](1,3)
\roughsurface(0,3)(5,0)(10,3)
\addtopsstyle{Beam}{beamalign=abs, beamangle=-45, arrows=->, arrowscale=2}
\multido{\r=0+0.3}{6}{%
\drawbeam[beampos=\r]{1}{2}{1}}
\end{pspicture}
\end{LTXexample}
% \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
% \Lcomp{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. \Lcomp{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
%
% \begin{optionlist}
% \boolitem[false]{showinterfaces}
% \ifGERMAN Zeigt alle Grenzflächen einer Komponente an.\fi
% \ifENGLISH Visualizes all interfaces of a component.\fi
%
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}
\begin{pspicture}(3,1.5)
  \psset[optexp]{showinterfaces, aomgratingcount=6}
  \addtopsstyle{IfcStyle}{linewidth=2\pslinewidth}
  \pnodes(0,1.5){A}(3,0.5){B}(3,1.5){C}
  \optaom[aomalign=symmetric](A)(B)(C){symmetric}
  \addtopsstyle{Beam}{arrows=->, linewidth=4\pslinewidth}
  \drawbeam[linecolor=red!50](A){}(C)
  \drawbeam[linecolor=red](A){}(B)
\end{pspicture}
\end{LTXexample}

\begin{LTXexample}
\begin{pspicture}(3,1.5)
  \psset[optexp]{showinterfaces, aomgratingcount=6}
  \addtopsstyle{IfcStyle}{linewidth=2\pslinewidth}
  \pnodes(0,1){A}(3,1){B}(3,1.5){C}
  \optaom[aomalign=straight](A)(B)(C){straight}
  \addtopsstyle{Beam}{arrows=->, linewidth=4\pslinewidth}
  \drawbeam[linecolor=red!50](A){}(C)
  \drawbeam[linecolor=red](A){}(B)
\end{pspicture}
\end{LTXexample}
% \iffalse
%</ignore>
% \fi
%
% \styleitem[linestyle=dashed, dash=1pt 1pt, linecolor=red!70!black]{IfcStyle}
% \ifGERMAN
% Bestimmt das Aussehen der mit \Lkeyword{showinterfaces} angezeigten
% Grenzflächen.
% \fi
% \ifENGLISH
% Determines the appearance of the interfaces, which are shown with
% \Lkeyword{showinterfaces}.
% \fi
% \end{optionlist}
%
% \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
% \Lcomp{mirror} ignores \opt{t} and \opt{b} and an \Lcomp{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$. This can be especially
% useful for round outer shapes, as the following examples shows.
% \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 \Lcomp{mirror}), oder auch \opt{r} und
% \opt{l} (z.B. bei \Lcomp{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$. Das kann gerade im Fall einer runden
% Außenform sehr hilfreich sein, wie das folgende Beispiel zeigt.
% \fi
% \iffalse
%<*ignore>
% \fi
\begin{LTXexample}[morekeywords={[21]extnode}]
\begin{pspicture}(2,1)
  \elecsynthesizer[extnode={-0.707,0.707}](1,0.5)(2,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.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)}
% \testextnodes{optarrowcomp}{(0,1.5)(3,1.5)}
% \testextnodes{optbarcomp}{(0,1.5)(3,1.5)}
% \begin{pspicture}(3,2)
%   \optdipole[optdipolesize=1](0,1.5)(3,1.5){}
%   \rput[t](1.5,0.9){\ttfamily\small
%     \begin{tabular}{@{}c@{}}\textbackslash optdipole\end{tabular}}
%   \makeatletter
%   \POE@extnodes[style=ExtNodeStyle, optdipolesize=1]{optdipole}
%   \makeatother
% \end{pspicture}
% \begin{pspicture}(3,2)
%   \transmissiongrating(0,1.5)(1.5,1.5)(3,1)
%   \rput[t](1.5,0.9){\ttfamily\small
%     \begin{tabular}{@{}c@{}}\textbackslash transmissiongrating\end{tabular}}
%   \makeatletter
%   \POE@extnodes[style=ExtNodeStyle]{transmissiongrating}
%   \makeatother
% \end{pspicture}
%
% \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\subsubsection*{Electrical components}\fi
% \ifGERMAN\subsubsection*{Elektrische Komponenten}\fi
%
% \testextnodes{eleccoupler}{(0,2)(0,1)(3,2)(3,1)}
% \testextnodes{elecmixer}{(0,1.6)(3,1.6)(1.5,0.9)}
% \testextnodes{elecsynthesizer}{(1,1.5)(3,1.5)}
%
%
% \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,0.5){B}
%   \optdetector(A)(B)
%   \drawbeam(A){}
%   \psdot(\oenodeIn{})\uput[-135](\oenodeIn{}){1}
%   \psdot(\oenodeOut{})\uput[-45](\oenodeOut{}){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.5){A}\pnode(1.5,1){B}\pnode(3,1.5){C}
%   \optprism[prismtype=reflective](A)(B)(C)
%   \drawbeam[raytrace=false](A){}(C)
%   \psdot(\oenodeIn{})\uput[110](\oenodeIn{}){1}
%   \psdot(\oenodeOut{})\uput[70](\oenodeOut{}){N}
%   \psdot(\oenodeIfc{2}{})\uput[90](\oenodeIfc{2}{}){2}
%   \rput[tl](0,0.42){\ttfamily\begin{tabular}{@{}l@{}}\textbackslash optprism\\prismtype=reflective\end{tabular}}
% \end{pspicture}%
%
% \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}%
% \hspace{\fill}%
% \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}%
% \showdipoleifc{optarrowcomp}%
% 
% \showdipoleifc{optbarcomp}\hspace{\fill}%
% \begin{pspicture}(0,-0.5)(3,1.7)
%   \pnode(0,0.7){A}\pnode(3,0.7){B}
%   \optdipole[optdipolesize=1](A)(B){}
%   \drawbeam(A){}(B)
%   \psdot(\oenodeIn{})\uput[135](\oenodeIn{}){1}
%   \psdot(\oenodeOut{})\uput[45](\oenodeOut{}){N}
%   \rput[bl](0,-0.4){\ttfamily\textbackslash optdipole}
% \end{pspicture}%
% \hspace{\fill}%
% \begin{pspicture}(0,-0.5)(3,1.7)
%   \pnode(0,0.7){A}\pnode(1.5,0.7){B}\pnode(3,0.4){C}
%   \transmissiongrating(A)(B)(C)
%   \drawbeam(A){}(C)
%   \psdot(\oenodeIn{})\uput[45](\oenodeIn{}){1, N}
%   \rput[bl](0,-0.4){\ttfamily\textbackslash transmissiongrating}
% \end{pspicture}%
%
% \noindent\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}%
% }%
% \begingroup
% \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}%
% \endgroup
%
% 
% \ifENGLISH\subsubsection*{Electrical components}\fi
% \ifGERMAN\subsubsection*{Elektrische Komponenten}\fi
% \begingroup
% \addtopsstyle{Wire}{arrows=->, arrowscale=1.5, arrowinset=0, arm=0.6}
% \noindent\begin{pspicture}(0, -0.5)(3,1.7)
%   \pnode(2,1.2){A}\pnode(3,1.2){B}
%   \elecsynthesizer(A)(B)
%   \psdot(\oenodeIn{})\uput[135](\oenodeIn{}){1}
%   \psdot(\oenodeOut{})\uput[45](\oenodeOut{}){N}
%   \rput[bl](0,-0.4){\ttfamily\textbackslash elecsynthesizer}
% \end{pspicture}\hspace{\fill}%
% \begin{pspicture}(0,-0.5)(3,1.7)
%   \pnode(0,1.2){A}\pnode(3,1.2){B}\pnode(1.2,0.1){C}
%   \elecmixer(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 elecmixer}
% \end{pspicture}\hspace{\fill}%
% \begin{pspicture}(0,-0.5)(3,1.7)
%   \pnode(0,1.7){A}\pnode(0,0.2){B}\pnode(3,1.7){C}\pnode(3,0.2){D}
%   \eleccoupler(A)(B)(C)(D)
%   \psdot(\oenodeIn{})\uput[120](\oenodeIn{}){1}
%   \psdot(\oenodeIfc{2}{})\uput[-120](\oenodeIfc{2}{}){2}
%   \psdot(\oenodeIfc{3}{})\uput[60](\oenodeIfc{3}{}){3}
%   \psdot(\oenodeOut{})\uput[-60](\oenodeOut{}){N}
%   \rput[bl](0,-0.4){\ttfamily\textbackslash eleccoupler}
% \end{pspicture}%
% \endgroup
%
% \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 4.3a}\label{sec:bwd-comp-4.3a}
%
% \begin{optionlist}
% \poeitem{prismtype}
% \ifGERMAN Die Option \Lkeyword{prismtype} war immer noch
% «zusammengeschustert» und die automatische Positionierung war recht
% willkürlich. Dies sollte nun endlich korrigiert sein, unter
% Option \Lkeyword{prismalign} ist ein entsprechendes Beispiel zu sehen.
% \fi
% \ifENGLISH The option \Lkeyword{prismtype} was still not correctly
% implemented, die automatic alignment was somewhat arbitrary. This
% should be finally fixed, an example is shown for option
% \Lkeyword{prismalign}.
% \fi
%
% \poeitem{\cs{optprism}}
% \ifGERMAN Die Positionierung der Beschriftung war nicht konsistent mit
% anderen Komponenten, der Bezugspunkt war nicht der Mittelpunkt und
% auch nicht fest. Das ist jetzt behoben, könnte aber leichte
% Korrekturen an bestehenden Skizzen erfordern.
% \fi
% \ifENGLISH The positioning of the label was not consistent with other
% components, the reference point was not the center point and did also
% depend on the component rotation. This is fixed now, but could mean
% little corrections for existing images.
% \fi
% 
% \end{optionlist} 
%
% \subsection{Version 4.3}\label{sec:bwd-comp-4.3}
%
% \begin{optionlist}
% \poeitem{\cs{rightangleprism}}
% \ifGERMAN Die Ausrichtung des \Lcomp{rightangleprism} und die
% Positionierung der Beschriftung war falsch. Das kommt aber nur zum
% tragen, wenn Eingangs- und Ausgangsvektor sehr unterschiedliche Längen
% haben.
% \fi
% \ifENGLISH The alignment of the \Lcomp{rightangleprism} and the
% positioning of the label was wrong. This became apparent only if the
% input and output vectors had very different lenghts. 
% \fi
% \end{optionlist}
% 
% \subsection{Version 4.2}\label{sec:bwd-comp-4.2}
%
% \begin{optionlist}
%   \poeitem{prismtype}
%   \ifGERMAN
%   Die in Version 4.1 eingeführte Option \Lkeyword{prismtype} benötigte
%   immer eine zusätzliche Drehung der Komponente um 180\textdegree. Das
%   entfällt nun, da die Komponentenausrichtung korrigiert wurde,
%   erfordert aber gegebenenfalls eine Korrektur von Skizzen, die mit
%   Version 4.1 erstellt wurden.
%   \fi
%   \ifENGLISH
%   The option \Lkeyword{prismtype}, introduced in version 4.1, always
%   needed an additional angle rotation of 180\textdegree. This is not
%   necessary anymore, the component behavior was corrected, but this may
%   require adjustment of drawings created with version 4.1.
%   \fi
% \end{optionlist}
% 
% \subsection{Version 4.0}\label{sec:bwd-comp-4.0}
% 
% \ifGERMAN Die Option \Lkeyword*{conn} und das alte, fehlerhafte
% Verfahren Strahlverbindungen zu zeichnen, wurde nun entfernt. Zur
% Migration älterer Dokumente siehe
% \prettyref{sec:bwd-comp-3.0-conn}. Damit wurde auch die Option
% \Lkeyword*{connjoin} überflüssig und wurde entfernt.
% \fi
% \ifENGLISH The option \Lkeyword*{conn} and the old, buggy code for beam
% connections was finally removed. To update older documents, see
% \prettyref{sec:bwd-comp-3.0-conn}. With this change also option
% \Lkeyword*{connjoin} became useless.
% \fi
%
% \ifENGLISH 
% The appearance of \Lcomp{optfiber} changed slightly, because the old
% implementation was buggy and the separation between the loops depended
% on the number of loops (see example below). Note, that to achieve a
% similar default look, the default value for \Lkeyword{fiberloopsep}
% was changed from 0.3 to 0.2. Therefore, the interface nodes are a bit
% closer together.
% \fi
% \ifGERMAN 
% Das Aussehen von \Lcomp{optfiber} hat sich etwas geändert, da in der
% vorherigen Implementierung der Abstand zwischen zwei Schleifen von der
% Anzahl der Schleifen abhing (siehe das Beispiel unten). Beachten Sie,
% dass die Voreinstellung für \Lkeyword{fiberloopsep} von 0.3 auf 0.2
% geändert wurde um ein ähnliches Aussehen bei Verwendung der
% Voreinstellungen zu erhalten. Dadurch sitzen die Eingangs- und
% Ausgangsknoten jedoch etwas näher zusammen (siehe unten).
% \fi
%
% \makeatletter
% \begin{pspicture}[showgrid](0,-0.3)(6,1.4)
% \newOptexpFiberDipole{optfiber@old}
% \def\optfiber@old@ref{%
%   \POE@setref{/@@x 0.3 \POE@key@fiberloops\space 1 sub mul 0.5 mul def }%
% }%
% \def\optfiber@old@nodes{%
%   \newOptexpFiberComp{{@@x neg 0} {@@x 0}}%
% \ignorespaces}%
% \def\optfiber@old@comp{%
%   \edef\@f@cnt{\POE@key@fiberloops\space}%
%   \edef\@f@r{0.4 }%
%   \edef\@f@sep{0.3 }%
%   \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}%
% \psset[optexp]{label=0.5 . b, showifcnodes}
% \optfiber@old[fiberloops=2](0,0.5)(2,0.5)
% \optfiber@old[fiberloops=3](2,0.5)(4,0.5){old}
% \optfiber@old[fiberloops=4](4,0.5)(6,0.5)
% \end{pspicture}
% \makeatother
% \hspace{\fill}
% \begin{pspicture}[showgrid](0,-0.3)(6,1.4)
% \psset[optexp]{label=0.5 . b, showifcnodes}
% \optfiber[fiberloops=2](0,0.5)(2,0.5)
% \optfiber[fiberloops=3](2,0.5)(4,0.5){new}
% \optfiber[fiberloops=4](4,0.5)(6,0.5)
% \end{pspicture}
% 
% \ifGERMAN Das Makro \Lcs*{newOptexpDipoleNolabel} wurde entfernt und
% kann ohne weitere Änderungen durch \Lcs{newOptexpDipole} ersetzt werden.
% \fi
% \ifENGLISH The macro \Lcs*{newOptexpDipoleNolabel} was removed and can
% be replaced by \Lcs{newOptexpDipole} without any further changes.
% \fi
%
% \ifGERMAN The alte Syntax mit \nxLcs{mycomp@iii} zur Definition eigener
% Komponenten wird nicht mehr unterstützt.
% \fi
% \ifENGLISH The old syntax of defining own components with
% \nxLcs{mycomp@iii} is not supported anymore.
% \fi
%
% \subsection{Version 3.3}\label{sec:bwd-comp-3.3}
%
% \begin{optionlist}
%   \poeitem{\textbackslash opttripole}
%   \ifGERMAN Der Ausgangswinkel für die Beschriftung des
%   \Lcomp{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
%   \Lcomp{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}. \Lcomp{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 \Lcomp{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 \Lcomp{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 \Lcomp{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 \Lcomp{fibercollimator} has only a fiber connection by
%   default, the beam must be drawn manually or with \Lkeyword{beam}
%   option.
%   \fi
%   \ifGERMAN Der \Lcomp{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
% \label{sec:bwd-comp-3.0-conn}
%
% \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}{%
%   \addchap{\indexname}%
%   \@mkboth{\indexname}{\indexname}%
% }
% \renewenvironment{theindex}{%
%   \idx@heading%
%   \index@preamble\par\nobreak
%   \thispagestyle{\indexpagestyle}\parindent\z@
%   \setlength{\parskip}{\z@ \@plus .3\p@}%
%   \setlength{\parfillskip}{\z@ \@plus 1fil}%
%   \let\item\@idxitem
% }{%
%  \clearpage
% }
% \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{fixed},
% \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}{6.1}{2022-02-06}
%   \item Fixed bug in \cs{oapmirror}
%   \end{release}
%   \begin{release}{6.0}{2021-02-26}
%   \item Modified \cs{wdmcoupler} to handle an arbitrary number of input nodes\see{comp:wdmcoupler}
%   \item Modified \cs{wdmsplitter} to handle an arbitrary number of output nodes\see{comp:wdmsplitter}
%   \item Removed deprecated \opt{lampscale}, use style \opt{CrystalLamp}.
%   \item Removed deprecated \opt{pollinewidth}, use style \opt{Polarization}.
%   \item Removed deprecated \cs{optgrid}, use \cs{optgrating}.
%   \item Removed deprecated \opt{optgridwidth}, use \opt{gratingwidth}.
%   \item Removed deprecated \opt{optgridheight}, use \opt{gratingheight}.
%   \item Removed deprecated \opt{optgriddepth}, use \opt{gratingdepth}.
%   \item Removed deprecated \opt{optgridcount}, use \opt{gratingcount}.
%   \item Removed deprecated \opt{optgridtype}, use \opt{gratingtype}.
%   \item Removed deprecated \opt{optgridlinewidth}, use \opt{gratinglinewidth}.
%   \item Removed deprecated \opt{align}, use \opt{coupleralign}.
%   \item Removed deprecated \opt{namingschema}.
%   \end{release}
%   \begin{release}{5.2}{2014-11-26}
%   \item Added component \cs{asphericlens}\see{comp:asphericlens}
%   \item Added component \cs{axicon}\see{comp:axicon}
%   \item Added component \cs{optwedge}\see{comp:optwedge}
%   \end{release}
%   \begin{release}{5.1}{2014-11-19}
%   \item Added component \cs{oapmirror}\see{comp:oapmirror}
%   \item Added support for filled beams with path interfaces.
%   \end{release}
%   \begin{release}{5.0}{2014-10-30}
%   \item Added support for arbitrary interface shapes (experimental,
%     requires the \opt{pst-intersect} package and \opt{pstricks}
%     version 2.53).
%   \item Added component \cs{parabolicmirror}\see{comp:parabolicmirror}
%   \end{release}
%   \begin{release}{4.10}{2014-06-04}
%   \item Added value \opt{firstcomp} to parameter \opt{beamalign}\see{prm:beamalign}
%   \item Modified \cs{optsource} to handle also the beam alignment\see{comp:optsource}
%   \end{release}
%   \begin{release}{4.9}{2014-06-03}
%   \item Added new component \cs{optsource}\see{comp:optsource}
%   \item Improved naming of the last component name, which can now be
%     accessed also by its number besides using \opt{N}.
%   \item Fixed bug related to \opt{extnodes} together with \opt{compname}
%   \end{release}
%   \begin{release}{4.8}{2014-02-28}
%   \item Added component \cs{optaom}\see{comp:optaom}
%   \item Added option \opt{beammode}\see{prm:beammode}
%   \item Added option \opt{showinterfaces}\see{prm:showinterfaces}
%   \end{release}
%   \begin{release}{4.7}{2014-01-12}
%   \item Added syntax \opt{<}\prm{num} for accessing relative component
%     IDs\see{sec:namingobj}
%   \end{release}
%   \begin{release}{4.6}{2013-11-27}
%   \item Added option \opt{extnodes}\see{prm:extnodes}
%   \item Added option \opt{optdipolecomp}\see{prm:optdipolecomp}
%   \item Added option \opt{opttripolecomp}\see{prm:opttripolecomp}
%   \end{release}
%   \begin{release}{4.5}{2013-07-21}
%   \item Added option \opt{usewirestyle}\see{prm:usewirestyle}
%   \item Added line style \opt{fade}, with options \opt{fadeto},
%     \opt{fadepoints}, \opt{fadefunc}, and
%     \opt{fadefuncname}\see{prm:fade}.
%   \end{release}
%   \begin{release}{4.4}{2013-07-14}
%   \item Added component \cs{transmissiongrating}\see{comp:transmissiongrating}
%   \item Modified \opt{innerlabel} to explicitly set \opt{labelalign=c}
%   \item Fixed trailing spaces in \opt{savebeampoints} (and \opt{savebeam}).
%   \item Allow Postscript code in \opt{angle}.
%   \end{release}
%   \begin{release}{4.3a}{2013-07-02}
%   \item Fixed tripole alignment bugs introduced in version 4.3.
%   \item Again fixed the alignment of reflective \cs{optprism}\see{prm:prismalign}
%   \item Fixed improper alignment of \cs{optprism} label\see{sec:bwd-comp-4.3a}
%   \end{release}
%   \begin{release}{4.3}{2013-06-28}
%   \item Added option \opt{raprismalign}\see{prm:raprismalign}
%   \item Fixed alignment of \cs{rightangleprism} and rotation of its
%     label.
%   \end{release}
%   \begin{release}{4.2}{2013-06-07}
%   \item Added option \opt{startinsidecount}\see{prm:startinsidecount}
%   \item Added option \opt{stopinsidecount}\see{prm:stopinsidecount}
%   \item Added option \opt{beampathcount}\see{prm:beampathcount}
%   \item Added option \opt{beamnodealign}\see{prm:beamnodealign}
%   \item Added \cs{oeBeamVecMedian}\see{cs:oeBeamVecMedian}
%   \item Added \cs{oeBeamCenter}\see{cs:oeBeamCenter}
%   \item Modified the orientation of a reflective
%     \cs{optprism}\see{sec:bwd-comp-4.2}
%   \item Fixed bug of \cs{optprism} and \cs{rightangleprism} inside
%     an \env{optexp} environment.
%   \item Fixed bug of wrong \cs{rightangleprism} rotation in special
%     cases.
%   \item Fixed buggy handling of multiple saved beams\see{prm:savebeam}
%   \end{release}
%   \begin{release}{4.1}{2013-05-21}
%   \item Added option \opt{prismtype}\see{prm:prismtype}
%   \end{release}
%   \begin{release}{4.0}{2013-04-15}
%   \item Added electrical components\see{chap:electrcomp}
%   \item Added wire connections with \cs{drawwire}\see{sec:drawwire}
%   \item Added component \cs{optarrowcomp}\see{comp:optarrowcomp}
%   \item Added component \cs{optbarcomp}\see{comp:optbarcomp}
%   \item Improved \cs{optdetector}\see{comp:optdetector}
%   \item Extended \cs{drawfiber} to support component
%     ranges\see{cs:drawfiber}
%   \item Extended \opt{couplersep} to support automatic
%     calculation\see{prm:couplersep}
%   \item Fixed appearance of \cs{optfiber}\see{sec:bwd-comp-4.0}
%   \item Fixed \opt{extnodealign} to affect also
%     multipoles\see{prm:extnodealign}
%   \item Fixed \opt{pswarning}.
%   \item Removed old, buggy beam connection code\see{sec:bwd-comp-4.0}
%   \item Removed option \opt{conn}\see{sec:bwd-comp-4.0}
%   \item Removed option \opt{connjoin}\see{sec:bwd-comp-4.0}
%   \item Removed \cs{newOptexpDipoleNolabel}\see{sec:bwd-comp-4.0}
%   \end{release}
%   \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{comp: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{comp: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{cs: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{comp:glanthompson}
%   \item Added access to beam vectors with \cs{oeBeamVec},
%     \cs{oeBeamVecUp} and \cs{oeBeamVecLow}\see{cs: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{comp: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{comp: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{cs:drawbeam}
%   \item Added wide beams with \cs{drawwidebeam}\see{cs:drawwidebeam}
%   \item Added \cs{drawfiber} for fiber connections\see{cs: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{comp:lens}
%   \item Added option \opt{platesize}\see{prm:platesize}
%   \item Added option \opt{phwidth}\see{comp:pinhole}
%   \item Modified option \opt{caxislength}\see{comp:crystal}
%   \item Deprecated option \opt{lampscale}\see{comp:crystal}
%   \item Added style \opt{CrystalCaxis}\see{comp:crystal}
%   \item Added style \opt{CrystalLamp}\see{comp:crystal}
%   \item Added option \opt{optboxsize}\see{comp:optbox}
%   \item Extended option \opt{detsize}\see{comp:optdetector}
%   \item Added style \opt{DetectorStyle}\see{comp:optdetector}
%   \item Removed deprecated \cs{detector}, use
%     \cs{optdetector}\see{comp:optdetector}
%   \item Extended option \opt{doveprismsize}\see{comp:doveprism}
%   \item Added style \opt{Polarization}\see{comp:polarization}
%   \item Deprecated option \opt{pollinewidth}\see{comp:polarization}
%   \item Removed option \opt{polwidth}\see{comp:polarization}
%   \item Removed option \opt{pol}\see{comp:polarization}
%   \item Added style \opt{VariableStyle}\see{comp:mirror}
%   \item Added mirror type \opt{semitrans}\see{prm:mirrortype}
%   \item Renamed \cs{optgrid} to \cs{optgrating}\see{comp:optgrating}
%   \item Renamed \opt{optgridwidth} to
%     \opt{gratingwidth}\see{comp:optgrating}
%   \item Renamed \opt{optgridheight} to
%     \opt{gratingheight}\see{comp:optgrating}
%   \item Renamed \opt{optgriddepth} to
%     \opt{gratingdepth}\see{comp:optgrating}
%   \item Renamed \opt{optgridcount} to
%     \opt{gratingcount}\see{comp:optgrating}
%   \item Renamed \opt{optgridtype} to
%     \opt{gratingtype}\see{comp:optgrating}
%   \item Renamed \opt{optgridlinewidth} to
%     \opt{gratinglinewidth}\see{comp:optgrating}
%   \item Added option \opt{prismalign}\see{comp:optprism}
%   \item Modified faulty alignment of
%     \cs{rightangleprism}\see{comp:rightangleprism}
%   \item Extended option \opt{optampsize}\see{comp:optamp}
%   \item Extended option \opt{optmzmsize}\see{comp:optmzm}
%   \item Added option \opt{polcontroltype}\see{comp:polcontrol}
%   \item Extended option \opt{isolatorsize}\see{comp:optisolator}
%   \item Added style \opt{IsolatorArrow}\see{comp:optisolator}
%   \item Extended option \opt{fdlsize}\see{comp:fiberdelayline}
%   \item Added style \opt{FdlArrow}\see{comp:fiberdelayline}
%   \item Extended option \opt{fiberpolsize}\see{comp:optfiberpolarizer}
%   \item Added component \cs{optcirculator}\see{comp:optcirculator}
%   \item Extended option \opt{couplersize}\see{comp:optcoupler}
%   \item Extended option \opt{couplertype}\see{comp:optcoupler}
%   \item Renamed option \opt{align} to
%     \opt{coupleralign}\see{comp:optcoupler}
%   \item Added style \opt{VariableCoupler}\see{comp:optcoupler}
%   \item Added style \opt{FilterStyle}\see{comp:optfilter}
%   \item Extended option \opt{fibercolsize}\see{comp:fibercollimator}
%   \item Removed deprecated option \opt{labelrelative}\see{sec:labels}
%   \item Removed deprecated option \opt{iwidth}\see{comp:pinhole}
%   \item Removed deprecated option \opt{owidth}\see{comp:pinhole}
%   \item Removed deprecated option \opt{bswidth}\see{comp: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{comp: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{comp:beamsplitter}
%   \item Extended \cs{fibercollimator} to use up to four reference
%     nodes\see{comp: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{comp:optdiode}
%     \item Added component \cs{pentaprism}\see{comp:pentaprism}
%     \item Added component
%       \cs{rightangleprism}\see{comp:rightangleprism}
%     \item Added component \cs{doveprism}\see{comp:doveprism}
%     \item Added component \cs{optprism}\see{comp: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{comp:optdetector}
%   \end{release}
%   \begin{release}{1.2}{2008-06-17}
%   \item Modified lens design to use interface curvatures\see{comp:lens}
%   \item Added options \opt{lensradiusleft} and
%     \opt{lensradiusright}\see{comp:lens}
%   \item Added option \opt{thicklens}\see{comp:lens}
%   \item Added option \opt{lenstype}\see{comp:lens}
%   \item Added option \opt{mirrorradius} (curved
%     mirrors)\see{comp:mirror}
%   \item Added option \opt{optgridtype} (binary
%     gratings)\see{comp: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{comp:polarization}
%   \item Renamed \opt{polwidth} to \opt{polsize}\see{comp:polarization}
%   \item Renamed \opt{pol} to \opt{poltype}\see{comp:polarization}
%   \item Renamed \opt{bswidth} to \opt{bssize}\see{comp:beamsplitter}
%   \item Renamed \opt{iwidth} to \opt{innerheight}\see{comp:pinhole}
%   \item Renamed \opt{owidth} to \opt{outerheight}\see{comp: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{ifthen}
\RequirePackage{pstricks}
\RequirePackage{pst-xkey}
\RequirePackage{pst-node}
\RequirePackage{pst-plot}
\RequirePackage{multido}
\RequirePackage{pst-eucl}
\RequirePackage{pst-intersect}
\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. The list is cleared when
% leaving the \nxLenv{pspicture} environment.
%    \begin{macrocode}
\gdef\POE@complist{}%
%    \end{macrocode}
% This hold a comma-separated list of the numbers of all saved beam end
% points in a \nxLenv{pspicture} environment. The list is used to delete
% all remaining Postscript information about the saved beams when
% leaving the current \nxLenv{pspicture}, as they may cause problems
% inside any following optexp-drawing.
%    \begin{macrocode}
\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}
\def\POE@Verb#1{\pst@Verb{\pst@optexpdict #1 end }}%
%    \end{macrocode}
% Save the pstricks-add line definition for use with the beams
%    \begin{macrocode}
\let\POE@tx@Line\tx@Line
\SpecialCoor
%    \end{macrocode}
%
% \section{Basic definitions}
% \subsection{Switches for the boolean keys}
% See respective key definitions for explanation.
%    \begin{macrocode}
\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@debug@showinterfaces
\newif\ifPOE@endbox
\newif\ifPOE@startbox
\newif\ifPOE@thicklens
\newif\ifPOE@usefiberstyle
\newif\ifPOE@usewirestyle
\newif\ifPOE@fiberin@
\newif\ifPOE@fiberin@top
\newif\ifPOE@fiberin@bottom
\newif\ifPOE@fiberout@
\newif\ifPOE@fiberout@top
\newif\ifPOE@fiberout@bottom
\newif\ifPOE@fiberpresetin@
\newif\ifPOE@fiberpresetin@top
\newif\ifPOE@fiberpresetin@bottom
\newif\ifPOE@fiberpresetout@
\newif\ifPOE@fiberpresetout@top
\newif\ifPOE@fiberpresetout@bottom
\newif\ifPOE@wirein@
\newif\ifPOE@wirein@top
\newif\ifPOE@wirein@bottom
\newif\ifPOE@wireout@
\newif\ifPOE@wireout@top
\newif\ifPOE@wireout@bottom
\newif\ifPOE@wirepresetin@
\newif\ifPOE@wirepresetin@top
\newif\ifPOE@wirepresetin@bottom
\newif\ifPOE@wirepresetout@
\newif\ifPOE@wirepresetout@top
\newif\ifPOE@wirepresetout@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
%    \end{macrocode}
% Save the current count at the end of the optexp-environment, before
% the second pass.
%    \begin{macrocode}
\newcount\POE@oldcnt
%    \end{macrocode}
% Count the temporal planes which are created for connections to nodes.
%    \begin{macrocode}
\newcount\POE@nodecnt
%    \end{macrocode}
% Count the number of input nodes of a wdmcoupler, or output nodes of a wdmsplitter
%    \begin{macrocode}
\newcount\POE@couplernodecount
%    \end{macrocode}
%
% \subsection{Fixed strings}
% These are all the fixed strings which are used as possible values for
% choicekeys.
%    \begin{macrocode}
\def\POE@str@absolute{absolute}
\def\POE@str@auto{auto}
\def\POE@str@bandpass{bandpass}
\def\POE@str@bandstop{bandstop}
\def\POE@str@binary{binary}
\def\POE@str@blazed{blazed}
\def\POE@str@bottom{bottom}
\def\POE@str@center{center}
\def\POE@str@circle{circle}
\def\POE@str@closed{closed}
\def\POE@str@connection{connection}
\def\POE@str@coupling{coupling}
\def\POE@str@cross{cross}
\def\POE@str@cube{cube}
\def\POE@str@custom{custom}
\def\POE@str@default{default}
\def\POE@str@diode{diode}
\def\POE@str@directional{directional}
\def\POE@str@ellipse{ellipse}
\def\POE@str@elliptic{elliptic}
\def\POE@str@extended{extended}
\def\POE@str@global{global}
\def\POE@str@highpass{highpass}
\def\POE@str@lcirc{lcirc}
\def\POE@str@left{left}
\def\POE@str@linear{linear}
\def\POE@str@lowpass{lowpass}
\def\POE@str@misc{misc}
\def\POE@str@none{none}
\def\POE@str@opened{opened}
\def\POE@str@parallel{parallel}
\def\POE@str@perp{perp}
\def\POE@str@piezo{piezo}
\def\POE@str@plain{plain}
\def\POE@str@plate{plate}
\def\POE@str@pulse{pulse}
\def\POE@str@quiet{quiet}
\def\POE@str@rcirc{rcirc}
\def\POE@str@rectangle{rectangle}
\def\POE@str@reflective{reflective}
\def\POE@str@relative{relative}
\def\POE@str@relgrav{relgrav}
\def\POE@str@right{right}
\def\POE@str@round{round}
\def\POE@str@sawtooth{sawtooth}
\def\POE@str@semitrans{semitrans}
\def\POE@str@sine{sine}
\def\POE@str@standard{standard}
\def\POE@str@symmetric{symmetric}
\def\POE@str@top{top}
\def\POE@str@transmittive{transmittive}
\def\POE@str@transparency{transparency}
\def\POE@str@triangle{triangle}
\def\POE@str@vector{vector}
\def\POE@str@verbose{verbose}
%    \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{IfcStyle}{linestyle=dashed, dash=1pt 1pt, linecolor=red!70!black}%
\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}
%
% Electrical connection stuff
%    \begin{macrocode}
\newpsstyle{Wire}{}
\define@key[psset]{optexp}{newWire}{%
  \newpsstyle{Wire}{#1}%
}
\define@key[psset]{optexp}{addtoWire}{%
  \addtopsstyle{Wire}{#1}%
}
\newpsstyle{WireIn}{style=Wire}
\define@key[psset]{optexp}{newWireIn}{%
  \newpsstyle{WireIn}{#1}%
}
\define@key[psset]{optexp}{addtoWireIn}{%
  \addtopsstyle{WireIn}{#1}%
}
\newpsstyle{WireIn1}{style=WireIn}
\define@key[psset]{optexp}{newWireIn1}{%
  \newpsstyle{WireIn1}{#1}%
}
\define@key[psset]{optexp}{addtoWireIn1}{%
  \addtopsstyle{WireIn1}{#1}%
}
\newpsstyle{WireIn2}{style=WireIn}
\define@key[psset]{optexp}{newWireIn2}{%
  \newpsstyle{WireIn2}{#1}%
}
\define@key[psset]{optexp}{addtoWireIn2}{%
  \addtopsstyle{WireIn2}{#1}%
}
\newpsstyle{WireOut}{style=Wire}
\define@key[psset]{optexp}{newWireOut}{%
  \newpsstyle{WireOut}{#1}%
}
\define@key[psset]{optexp}{addtoWireOut}{%
  \addtopsstyle{WireOut}{#1}%
}
\newpsstyle{WireOut1}{style=WireOut}
\define@key[psset]{optexp}{newWireOut1}{%
  \newpsstyle{WireOut1}{#1}%
}
\define@key[psset]{optexp}{addtoWireOut1}{%
  \addtopsstyle{WireOut1}{#1}%
}
\newpsstyle{WireOut2}{style=WireOut}
\define@key[psset]{optexp}{newWireOut2}{%
  \newpsstyle{WireOut2}{#1}%
}
\define@key[psset]{optexp}{addtoWireOut2}{%
  \addtopsstyle{WireOut2}{#1}%
}
\newpsstyle{ElecComp}{}
%    \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@choicekey[psset]{optexp}{usewirestyle}%
  [\val\nr]{true,false}[true]{%
    \psset[optexp]{usefiberstyle=false}%
    \ifcase\nr\relax
      \POE@usewirestyletrue
    \or
      \POE@usewirestylefalse
    \fi}%
\define@boolkey[psset]{optexp}[POE@]{usewirestyle}[true]{}
\define@boolkey[psset]{optexp}[POE@debug@]{showoptdots}[true]{}
\define@boolkey[psset]{optexp}[POE@debug@]{showifcnodes}[true]{}
\define@boolkey[psset]{optexp}[POE@debug@]{showinterfaces}[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@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, labelalign=c}%
   \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=180
}%
%    \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}{extnodes}{%
  \edef\POE@key@extnode{#1}%
  \ifx\@empty\POE@key@extnode
    \edef\POE@key@extnode@cnt{1}%
    \edef\POE@key@extnode@xrefs{0 }%
    \edef\POE@key@extnode@yrefs{0 }%
  \else
    \def\POE@key@extnode@xrefs{}%
    \def\POE@key@extnode@yrefs{}%
    \psForeach{\POE@tempD}{#1,}{%
      \ifx\POE@tempD\@empty
        \advance\psLoopIndex by -1
      \else
        \pst@expandafter\POE@psset@@extnode{\POE@tempD}\@empty,,\@nil
        \edef\POE@key@extnode@xrefs{\POE@key@extnode@xrefs\POE@key@extnode@xref\space}%
        \edef\POE@key@extnode@yrefs{\POE@key@extnode@yrefs\POE@key@extnode@yref\space}%
      \fi
    }%
    \edef\POE@key@extnode@cnt{\the\psLoopIndex}%
  \fi
}%
%    \end{macrocode}
% Need to have two options 'extnode' and 'extnodes' to allow extnode={-0.5,1} without 
%    \begin{macrocode}
\define@key[psset]{optexp}{extnode}{%
  \edef\POE@key@extnode{#1}%
  \edef\POE@key@extnode@cnt{1}%
  \ifx\@empty\POE@key@extnode
    \edef\POE@key@extnode@xrefs{0 }%
    \edef\POE@key@extnode@yrefs{0 }%
  \else
    \pst@expandafter\POE@psset@@extnode{#1}\@empty,,\@nil
    \edef\POE@key@extnode@xrefs{\POE@key@extnode@xref}%
    \edef\POE@key@extnode@yrefs{\POE@key@extnode@yref}%
  \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=absolute
}%
%    \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}
\edef\POE@str@basicname@default{@}%
\edef\POE@str@basicname@prefix{OE@}%
\gdef\POE@str@basicname@sep{}%
\edef\POE@str@extnode@postfix{Ext}%
\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}
%
%    \begin{macrocode}
\define@key[psset]{optexp}{asphereheight}{%
  \pst@checknum{#1}\POE@key@asphereheight
}%
\define@key[psset]{optexp}{aspherewidth}{%
  \pst@checknum{#1}\POE@key@aspherewidth
}%
\define@key[psset]{optexp}{asphereradiusleft}{%
  \pst@checknum{#1}\POE@key@asphereradiusleft
}%
\define@key[psset]{optexp}{asphereradiusright}{%
  \pst@checknum{#1}\POE@key@asphereradiusright
}%
\define@key[psset]{optexp}{asphereconstant}{%
  \pst@checknum{#1}\POE@key@asphereconstant
}%
\define@key[psset]{optexp}{aspherecoefficients}{%
  \pst@expandafter\POE@psset@@aspherecoefficients{#1} {} {} {} {} {}\@nil
}%
\def\POE@psset@@aspherecoefficients#1 #2 #3 #4 #5\@nil{%
  \def\POE@key@asphereAfour{0}%
  \def\POE@key@asphereAsix{0}%
  \def\POE@key@asphereAeight{0}%
  \def\POE@key@asphereAten{0}%
  \ifx\\#1\\\else
    \def\POE@key@asphereAfour{#1}%
    \ifx\\#2\\\else
      \def\POE@key@asphereAsix{#2}%
      \ifx\\#3\\\else
        \def\POE@key@asphereAeight{#3}%
        \ifx\\#4\\\else
          \def\POE@key@asphereAten{#4}%
        \fi
      \fi
    \fi
  \fi
}%
\psset[optexp]{%
  aspherewidth=0,
  asphereheight=1,
  asphereconstant=-1,
  asphereradiusleft=1,
  aspherecoefficients=0,
  asphereradiusright=0
}
%    \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]{}
\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]{optboxsize=1.4 0.8}%
%    \end{macrocode}
%
% Box
%    \begin{macrocode}
\define@key[psset]{optexp}{sourcewidth}{%
  \pst@checknum{#1}\POE@key@sourcewidth
}
\define@key[psset]{optexp}{sourceheight}{%
  \pst@checknum{#1}\POE@key@sourceheight
}
\define@key[psset]{optexp}{sourcesize}{%
  \pst@expandafter\POE@psset@@sourcesize{#1} {} {} {}\@nil
}%
\def\POE@psset@@sourcesize#1 #2 #3\@nil{%
  \ifx\\#2\\%
    \PackageWarning{pst-optexp}{%
      Parameter 'sourcesize' requires two numbers.}%
  \fi
  \psset[optexp]{sourcewidth=#1, sourceheight=#2}%
}%
\psset[optexp]{sourcesize=1.4 0.8}%
%    \end{macrocode}
%
% arrowbox
%    \begin{macrocode}
\define@key[psset]{optexp}{arrowcompwidth}{%
  \pst@checknum{#1}\POE@key@arrowcompwidth
}
\define@key[psset]{optexp}{arrowcompheight}{%
  \pst@checknum{#1}\POE@key@arrowcompheight
}
\define@key[psset]{optexp}{arrowcompsize}{%
  \pst@expandafter\POE@psset@@arrowcompsize{#1} {} {} {}\@nil
}%
\def\POE@psset@@arrowcompsize#1 #2 #3\@nil{%
  \ifx\\#2\\%
    \psset[optexp]{arrowcompwidth=#1, arrowcompheight=#1}%
  \else
    \psset[optexp]{arrowcompwidth=#1, arrowcompheight=#2}%
  \fi
}%
\define@key[psset]{optexp}{arrowcompangle}{%
  \pst@checknum{#1}\POE@key@arrowcompangle
}%
\define@choicekey+[psset]{optexp}{arrowcompshape}%
  [\val\nr]{circle, rectangle}%
  {\edef\POE@key@arrowcompshape{#1}}%
  {\PackageError{pst-optexp}{Unknown value '\val' for arrowcompshape}}
\psset[optexp]{%
  arrowcompsize=1.4 0.8,
  arrowcompangle=70,
  arrowcompshape=rectangle
}%
\newpsstyle{ArrowCompStyle}{arrowinset=0, arrows=->}%
%    \end{macrocode}
% BarBox
%    \begin{macrocode}
\define@key[psset]{optexp}{barcompwidth}{%
  \pst@checknum{#1}\POE@key@barcompwidth
}
\define@key[psset]{optexp}{barcompheight}{%
  \pst@checknum{#1}\POE@key@barcompheight
}
\define@key[psset]{optexp}{barcompsize}{%
  \pst@expandafter\POE@psset@@barcompsize{#1} {} {} {}\@nil
}%
\def\POE@psset@@barcompsize#1 #2 #3\@nil{%
  \ifx\\#2\\%
    \psset[optexp]{barcompwidth=#1, barcompheight=#1}%
  \else
    \psset[optexp]{barcompwidth=#1, barcompheight=#2}%
  \fi
}%
\define@key[psset]{optexp}{barcompangle}{%
  \pst@checknum{#1}\POE@key@barcompangle
}%
\define@choicekey+[psset]{optexp}{barcompshape}%
  [\val\nr]{circle, rectangle}%
  {\edef\POE@key@barcompshape{#1}}%
  {\PackageError{pst-optexp}{Unknown value '\val' for barcompshape}}
\psset[optexp]{%
  barcompsize=1.4 0.8,
  barcompangle=70,
  barcompshape=rectangle
}%
\newpsstyle{BarCompStyle}{}%
%    \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
}
%    \end{macrocode}
% This is defined manually, to avoid printing the warning inside the key definition above.
%    \begin{macrocode}
\newpsstyle{Polarization}{%
  linewidth=0.7\pslinewidth, 
  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}
%
% Parabolic mirror
%    \begin{macrocode}
\define@key[psset]{optexp}{parmirrorwidth}{%
  \pst@checknum{#1}\POE@key@parmirrorwidth
}
\define@key[psset]{optexp}{parmirrorheight}{%
  \pst@checknum{#1}\POE@key@parmirrorheight
}
\psset[optexp]{%
  parmirrorwidth=1,
  parmirrorheight=1
}%
%    \end{macrocode}
%
% Off-axis parabolic mirror
%    \begin{macrocode}
\define@key[psset]{optexp}{oapmirroraperture}{%
  \pst@expandafter\POE@psset@@oapmirroraperture{#1} {} {} {}\@nil
}%
\def\POE@psset@@oapmirroraperture#1 #2 #3\@nil{%
  \ifx\\#2\\%
    \def\POE@key@oapmirroraperture@outer{#1 0.5 mul}
    \def\POE@key@oapmirroraperture@inner{#1 0.5 mul}
  \else
    \pst@checknum{#1}\POE@key@oapmirroraperture@inner
    \pst@checknum{#2}\POE@key@oapmirroraperture@outer
  \fi
}%
\psset[optexp]{oapmirroraperture=1}
%    \end{macrocode}
%
% Axicon
%    \begin{macrocode}
\define@key[psset]{optexp}{axiconheight}{%
  \pst@checknum{#1}\POE@key@axiconheight
}%
\define@key[psset]{optexp}{axiconwidth}{%
  \pst@checknum{#1}\POE@key@axiconwidth
}%
\define@key[psset]{optexp}{axiconangle}{%
  \pst@checknum{#1}\POE@key@axiconangle
}%
\psset[optexp]{axiconheight=1.5, axiconwidth=0.4, axiconangle=10}
%    \end{macrocode}
%
% Wedge
%    \begin{macrocode}
\define@key[psset]{optexp}{wedgeangles}{%
  \pst@expandafter\POE@psset@@wedgeangles{#1} {} {} {}\@nil
}%
\def\POE@psset@@wedgeangles#1 #2 #3\@nil{%
  \pst@checknum{#1}\POE@key@wedgeangleleft
  \ifx\\#2\\%
    \pst@checknum{#1}\POE@key@wedgeangleright
  \else
    \pst@checknum{#2}\POE@key@wedgeangleright
  \fi
}%
\define@key[psset]{optexp}{wedgeangleleft}{%
  \pst@checknum{#1}\POE@key@wedgeangleleft
}%
\define@key[psset]{optexp}{wedgeangleright}{%
  \pst@checknum{#1}\POE@key@wedgeangleright
}%
\define@key[psset]{optexp}{wedgeheight}{%
  \pst@checknum{#1}\POE@key@wedgeheight
}%
\define@key[psset]{optexp}{wedgewidth}{%
  \pst@checknum{#1}\POE@key@wedgewidth
}%
\psset[optexp]{%
  wedgeangles=0 10,
  wedgeheight=0.8,
  wedgewidth=0
}%
%    \end{macrocode}
% Grating
%    \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
}
\define@choicekey+[psset]{optexp}{raprismalign}[\val\nr]%
  {auto,center}%
  {\def\POE@key@raprismalign{#1}}%
  {\PackageError{pst-optexp}{Unknown value '\val' for raprismalign}}%
\psset[optexp]{%
  raprismsize=1.5,
  raprismalign=auto
}
%    \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}}%
\define@choicekey+[psset]{optexp}{prismtype}[\val\nr]%
  {transmittive, reflective, coupling}%
  {\def\POE@key@prismtype{#1}}%
  {\PackageError{pst-optexp}{Unknown value '\val' for prismtype}}%
\psset[optexp]{%
  prismsize=1,
  prismangle=60,
  prismalign=auto,
  prismtype=transmittive
}%
%    \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
}%
\define@key[psset]{optexp}{optdipolecomp}{%
  \def\POE@key@optdipolecomp{#1}%
}
\define@key[psset]{optexp}{opttripolecomp}{%
  \def\POE@key@opttripolecomp{#1}%
}
\psset[optexp]{%
  optdipolesize=0 0,
  optdipolecomp=,
  opttripolecomp=%
}%
%    \end{macrocode}
%
% acousto-optic modulator
%    \begin{macrocode}
\define@key[psset]{optexp}{aomwidth}{%
  \pst@checknum{#1}\POE@key@aomwidth
}%
\define@key[psset]{optexp}{aomheight}{%
  \pst@checknum{#1}\POE@key@aomheight
}%
\define@key[psset]{optexp}{aomsize}{%
  \pst@expandafter\POE@psset@@aomsize{#1} {} {} {}\@nil
}%
\define@key[psset]{optexp}{aomgratingcount}{%
  \edef\POE@key@aomgratingcount{#1}%
}%
\define@choicekey+[psset]{optexp}{aomalign}%
  [\val\nr]{sym,symmetric,straight}%
  {%
    \ifcase\nr\relax
      \let\POE@key@aomalign\POE@str@symmetric
    \else
      \def\POE@key@aomalign{#1}%
    \fi
  }%
  {\PackageError{pst-optexp}{Unknown value '\val' for aomalign}}%
\define@choicekey+[psset]{optexp}{aomreflalign}%
  [\val\nr]{perp,parallel}%
  {\def\POE@key@aomreflalign{#1}}%
  {\PackageError{pst-optexp}{Unknown value '\val' for aomreflalign}}%
\def\POE@psset@@aomsize#1 #2 #3\@nil{%
  \ifx\\#2\\%
    \PackageWarning{pst-optexp}{%
      Parameter 'aomsize' requires two numbers.}%
  \fi
  \psset[optexp]{aomwidth=#1, aomheight=#2}%
}%
\define@key[psset]{optexp}{aomcomp}{%
  \def\POE@key@aomcomp{#1}%
}%
\define@key[psset]{optexp}{diffractionorders}{%
  \def\POE@key@diffractionorders{#1}%
}%
\define@key[psset]{optexp}{beamdiffractionorder}{%
  \def\POE@key@beamdiffractionorder{#1}%
}%
\psset[optexp]{%
  aomsize=1.5 1, 
  aomcomp=default, 
  aomalign=sym,
  aomreflalign=parallel,
  aomgratingcount=9,
  diffractionorders=2,
  beamdiffractionorder=
}%
%    \end{macrocode}
%
% \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.2
}%
%    \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}{%
  \edef\POE@key@couplersep{#1}%
}
\define@choicekey+[psset]{optexp}{couplertype}%
  [\val\nr]{none,elliptic,ellipse,cross,rectangle}%
  {%
    \edef\POE@key@couplertype{#1}
    \ifx\POE@key@couplertype\POE@str@elliptic
      \let\POE@key@couplertype\POE@str@ellipse
    \fi
  }%
  {\PackageError{pst-optexp}{Unknown value '\val' for couplertype}}
\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{Electrical components}
%
% \subsubsection{elecmixer}
%    \begin{macrocode}
\define@key[psset]{optexp}{elecmixersize}{%
  \pst@checknum{#1}\POE@key@elecmixersize
}%
\psset[optexp]{elecmixersize=0.8}%
%    \end{macrocode}
%
% \subsubsection{eleccoupler}
%    \begin{macrocode}
\define@key[psset]{optexp}{eleccouplersize}{%
  \pst@expandafter\POE@psset@@eleccouplersize{#1} {} {} {}\@nil
}%
\def\POE@psset@@eleccouplersize#1 #2 #3\@nil{%
  \pst@checknum{#1}\POE@key@eleccouplerwidth
  \ifx\\#2\\%
    \pst@checknum{#1}\POE@key@eleccouplerheight
  \else
    \pst@checknum{#2}\POE@key@eleccouplerheight
  \fi
}%
\define@key[psset]{optexp}{eleccouplersep}{%
  \edef\POE@key@eleccouplersep{#1}%
}
\define@choicekey+[psset]{optexp}{eleccouplertype}%
  [\val\nr]{standard, directional}%
  {\edef\POE@key@eleccouplertype{#1}}%
  {\PackageError{pst-optexp}{Unknown value '\val' for eleccouplertype}}%
\define@choicekey+[psset]{optexp}{eleccouplerinput}%
  [\val\nr]{left, right}%
  {\edef\POE@key@eleccouplerinput{#1}}%
  {\PackageError{pst-optexp}{Unknown value '\val' for eleccouplerinput}}%
\define@choicekey+[psset]{optexp}{eleccoupleralign}%
  [\val\nr]{t,b,c,top,bottom,center}%
  {%
    \ifcase\nr\relax
      \let\POE@key@eleccoupleralign\POE@str@top
    \or
      \let\POE@key@eleccoupleralign\POE@str@bottom
    \or
      \let\POE@key@eleccoupleralign\POE@str@center
    \else
      \def\POE@key@eleccoupleralign{#1}%
    \fi}%
  {\PackageError{pst-optexp}{Unknown value '\val' for eleccoupleralign}}
\psset[optexp]{%
  eleccouplersize=0.8,
  eleccouplersep={},
  eleccoupleralign=center,
  eleccouplertype=standard,
  eleccouplerinput=left
}%
%    \end{macrocode}
%
%    \begin{macrocode}
\define@key[psset]{optexp}{synthsize}{%
  \pst@expandafter\POE@psset@@synthsize{#1} {} {} {}\@nil
}%
\def\POE@psset@@synthsize#1 #2 #3\@nil{%
  \pst@checknum{#1}\POE@key@synthwidth
  \ifx\\#2\\%
    \pst@checknum{#1}\POE@key@synthheight
  \else
    \pst@checknum{#2}\POE@key@synthheight
  \fi
}%
\define@key[psset]{optexp}{synthrectwidth}{%
  \pst@checknum{#1}\POE@key@synthrectwidth
}%
\define@choicekey+[psset]{optexp}{synthshape}%
  [\val\nr]{circle, rectangle}%
  {\edef\POE@key@synthshape{#1}}%
  {\PackageError{pst-optexp}{Unknown value '\val' for synthshape}}
\define@choicekey+[psset]{optexp}{synthtype}%
  [\val\nr]{sine, pulse, rectangle, triangle, sawtooth, custom}%
  {\edef\POE@key@synthtype{#1}}%
  {\PackageError{pst-optexp}{Unknown value '\val' for synthtype}}
\newpsstyle{SynthStyle}{}
\psset[optexp]{%
  synthsize=0.8,
  synthshape=circle,
  synthtype=sine,
  synthrectwidth=0.2
}%
%    \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@choicekey+[psset]{optexp}{beammode}%
  [\val\nr]{trans,refl,reflective,transmittive,auto}%
  {\ifcase\nr\relax
      \let\POE@key@beammode\POE@str@transmittive
    \or
      \let\POE@key@beammode\POE@str@reflective
    \else
      \def\POE@key@beammode{#1}%
    \fi}%
  {\PackageError{pst-optexp}{Unknown value '\val' for beammode}}

\define@boolkey[psset]{optexp}[POE@]{startinside}[true]{}%
\define@boolkey[psset]{optexp}[POE@]{stopinside}[true]{}%
\define@key[psset]{optexp}{startinsidecount}{%
  \pst@checknum{#1}\POE@key@startinsidecount
}
\define@key[psset]{optexp}{stopinsidecount}{%
  \pst@checknum{#1}\POE@key@stopinsidecount
}
\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@choicekey+[psset]{optexp}{beamnodealign}%
  [\val\nr]{vec, conn, vector, connection}%
  {%
    \ifcase\nr\relax
      \let\POE@key@beamnodealign\POE@str@vector
    \or
      \let\POE@key@beamnodealign\POE@str@connection
    \else
      \def\POE@key@beamnodealign{#1}%
    \fi
  }%
  {\PackageError{pst-optexp}{Unknown value '\val' for beamnodealign}}
\define@key[psset]{optexp}{beampathskip}{%
  \pst@checknum{#1}\POE@key@beampathskip
}%
\define@key[psset]{optexp}{beampathcount}{%
  \pst@getint{#1}\POE@key@beampathcount
}%
\define@choicekey+[psset]{optexp}{beamalign}%
  [\val\nr]{rel,abs,relative,absolute,firstcomp}%
  {%
    \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}%
}%
\define@choicekey[psset]{optexp}{fadeto}[\val\nr]{white,black,transparency}{%
  \def\POE@key@fadeto{#1}%
}%
\define@key[psset]{optexp}{fadefunc}{%
  \def\POE@key@fadefunc{#1}%
}%
\define@key[psset]{optexp}{fadefuncname}{%
  \def\POE@key@fadefuncname{#1}%
}%
\define@key[psset]{optexp}{fadepoints}{%
  \def\POE@key@fadepoints{#1}%
}%
\def\psls@fade{%
  \pst@optexpdict
    \ifx\POE@key@fadefunc\@empty\else
      /fadefunc@custom {\POE@key@fadefunc} def
    \fi
    /fadecorrect \ifx\POE@key@fadeto\POE@str@transparency 0 \else 0.1 \fi def
    \pst@usecolor\pslinecolor
    \POE@key@fadepoints\space
    \psk@strokeopacityalpha
    currentdict /fadeto@\POE@key@fadeto\space dup 3 1 roll known not { pop /fadeto@white } if load
    currentdict /fadefunc@\POE@key@fadefuncname\space dup 3 1 roll known not { pop /fadefunc@linear } if load
    FadeStroke
  end
}%
\psset[optexp]{%
  raytrace=true
  ,useNA=true
  ,beamnodealign=connection
  ,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
  ,beammode=auto
  ,n=1.5
  ,beampathskip=0
  ,beampathcount=-1
  ,stopinsidecount=-1
  ,startinsidecount=-1
  ,ArrowInsideMinLength=0.2
  ,ArrowInsideMaxLength=-1
  ,fadepoints=200
  ,fadeto=white
  ,fadefunc=\@empty
  ,fadefuncname=linear
}%
%    \end{macrocode}
%
% \subsection{Fiber-connection parameters}
% Select which fibers are drawn automatically. 
%    \begin{macrocode}
\define@key[psset]{optexp}{fiber}[all]{%
  \POE@psset@fibercheck#1\@nil
}
%    \end{macrocode}
% Check which components are affected by the fiber parameter. * is only for 
% fiber-optical components, + refers to all components but the fiber-optical 
% ones, otherwise all components are affected.
%    \begin{macrocode}
\def\POE@psset@fibercheck#1#2\@nil{%
  \ifx#1*\relax
    \ifx\\#2\\%
      \setkeys[psset]{optexp}{fiber@preset=all}%
    \else
      \setkeys[psset]{optexp}{fiber@preset=#2}%
    \fi
  \else\ifx#1+\relax
    \ifx\\#2\\%
      \setkeys[psset]{optexp}{fiber@all=all}%
    \else
      \setkeys[psset]{optexp}{fiber@all=#2}%
    \fi
    \POE@unset@wire
  \else
    \setkeys[psset]{optexp}{fiber@all=#1#2}%
    \setkeys[psset]{optexp}{fiber@preset=#1#2}%
    \POE@unset@wire
  \fi\fi
}%
\def\POE@unset@wire{%
  \ifPOE@fiberin@
    \setkeys[psset]{optexp}{wirepresetin@=false}%
  \fi
  \ifPOE@fiberout@
    \setkeys[psset]{optexp}{wirepresetout@=false}%
  \fi
  \ifPOE@fiberin@top
    \setkeys[psset]{optexp}{wirepresetin@top=false}%
  \fi
  \ifPOE@fiberin@bottom
    \setkeys[psset]{optexp}{wirepresetin@bottom=false}%
  \fi
  \ifPOE@fiberout@top
    \setkeys[psset]{optexp}{wirepresetout@top=false}%
  \fi
  \ifPOE@fiberout@bottom
    \setkeys[psset]{optexp}{wirepresetout@bottom=false}%
  \fi
}%
%    \end{macrocode}
% Set the fiber parameters for fiber-optical components only (use fiber=*...).
%    \begin{macrocode}
\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{%
  \setkeys[psset]{optexp}{%
    fiberpresetin@=false, fiberpresetout@=false,
    fiberpresetin@top=false, fiberpresetin@bottom=false, 
    fiberpresetout@top=false, fiberpresetout@bottom=false}%
}%
\def\POE@getfiberpreset@all{%
  \setkeys[psset]{optexp}{%
    fiberpresetin@, fiberpresetout@,
    fiberpresetin@top, fiberpresetin@bottom, 
    fiberpresetout@top, fiberpresetout@bottom}%
}%
\def\POE@getfiberpreset@t{%
  \setkeys[psset]{optexp}{%
    fiberpresetin@bottom=false, fiberpresetout@bottom=false}%
}%
\def\POE@getfiberpreset@b{%
  \setkeys[psset]{optexp}{%
    fiberpresetin@top=false, fiberpresetout@top=false}%
}%
\def\POE@getfiberpreset@l{%
  \setkeys[psset]{optexp}{%
    fiberpresetout@=false,
    fiberpresetout@top=false,
    fiberpresetout@bottom=false}%
}%
\def\POE@getfiberpreset@r{%
  \setkeys[psset]{optexp}{%
    fiberpresetin@=false,
    fiberpresetin@top=false,
    fiberpresetin@bottom=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{%
  \setkeys[psset]{optexp}{%
    fiberin@=false, fiberout@=false,
    fiberin@top=false, fiberin@bottom=false, 
    fiberout@top=false, fiberout@bottom=false}%
}%
\def\POE@getfiber@all{%
  \setkeys[psset]{optexp}{%
    fiberin@, fiberout@,
    fiberin@top, fiberin@bottom, 
    fiberout@top, fiberout@bottom}%
}%
\def\POE@getfiber@t{%
  \setkeys[psset]{optexp}{%
    fiberin@bottom=false, fiberout@bottom=false}%
}%
\def\POE@getfiber@b{%
  \setkeys[psset]{optexp}{%
    fiberin@top=false, fiberout@top=false}%
}%
\def\POE@getfiber@l{%
  \setkeys[psset]{optexp}{%
    fiberout@=false, fiberout@top=false, fiberout@bottom=false}%
}%
\def\POE@getfiber@r{%
  \setkeys[psset]{optexp}{%
    fiberin@=false, fiberin@top=false, fiberin@bottom=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@]{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@]{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
}%

% \subsection{Wire connection parameters}
% Select which wires are drawn automatically. 
% Note, this part is equivalent to the fiber connection parameters, only 'fiber' is replace by 'wire'.
%    \begin{macrocode}
\define@key[psset]{optexp}{wire}[all]{%
  \POE@psset@wirecheck#1\@nil
}
%    \end{macrocode}
% Check which components are affected by the wire parameter:
% * is only for electrical components
% + refers to all components but the electrical ones,
% otherwise all components are affected.
%    \begin{macrocode}
\def\POE@psset@wirecheck#1#2\@nil{%
  \ifx#1*\relax
    \ifx\\#2\\%
      \setkeys[psset]{optexp}{wire@preset=all}%
    \else
      \setkeys[psset]{optexp}{wire@preset=#2}%
    \fi
  \else\ifx#1+\relax
    \ifx\\#2\\%
      \setkeys[psset]{optexp}{wire@all=all}%
    \else
      \setkeys[psset]{optexp}{wire@all=#2}%
    \fi
    \POE@unset@fiber
  \else
    \setkeys[psset]{optexp}{wire@all=#1#2, wire@preset=#1#2}%
    \POE@unset@fiber
  \fi\fi
}%
\def\POE@unset@fiber{%
  \ifPOE@wirein@
    \setkeys[psset]{optexp}{fiberpresetin@=false, fiberin@=false}%
  \fi
  \ifPOE@wireout@
    \setkeys[psset]{optexp}{fiberpresetout@=false, fiberout@=false}%
  \fi
  \ifPOE@wirein@top
    \setkeys[psset]{optexp}{fiberpresetin@top=false, fiberin@top=false}%
  \fi
  \ifPOE@wirein@bottom
    \setkeys[psset]{optexp}{fiberpresetin@bottom=false, fiberin@bottom=false}%
  \fi
  \ifPOE@wireout@top
    \setkeys[psset]{optexp}{fiberpresetout@top=false, fiberout@top=false}%
  \fi
  \ifPOE@wireout@bottom
    \setkeys[psset]{optexp}{fiberpresetout@bottom=false, fiberout@bottom=false}%
  \fi
}%
%    \end{macrocode}
% Set the fiber parameters for fiber-optical components only (use fiber=*...).
%    \begin{macrocode}
\define@choicekey*+[psset]{optexp}{wire@preset}%
  [\val\nr]{false,none,true,all}[all]{%
  \ifcase\nr\relax
    \POE@getwirepreset@none
  \or
    \POE@getwirepreset@none
  \or
    \POE@getwirepreset@all
  \or
    \POE@getwirepreset@all
  \fi
}{%
  \ifx\@empty\val
    \POE@getwirepreset@none
  \else
    \pst@expandafter\POE@psset@@wirepreset{#1}\@empty,,\@nil
  \fi
}%
\def\POE@psset@@wirepreset#1#2,#3,#4\@nil{%
  \POE@getwirepreset@all
  \ifx\\#3\\%
    \@nameuse{POE@getwirepreset@#1}%
    \@nameuse{POE@getwirepreset@#2}%
  \fi
}%
\def\POE@getwirepreset@none{%
  \setkeys[psset]{optexp}{%
    wirepresetin@=false, wirepresetout@=false,
    wirepresetin@top=false, wirepresetin@bottom=false, 
    wirepresetout@top=false, wirepresetout@bottom=false}%
}%

\def\POE@getwirepreset@all{%
  \setkeys[psset]{optexp}{%
    wirepresetin@, wirepresetout@,
    wirepresetin@top, wirepresetin@bottom, 
    wirepresetout@top, wirepresetout@bottom}%
}%
\def\POE@getwirepreset@t{%
  \setkeys[psset]{optexp}{%
    wirepresetin@bottom=false, wirepresetout@bottom=false}%
}%
\def\POE@getwirepreset@b{%
  \setkeys[psset]{optexp}{%
    wirepresetin@top=false, wirepresetout@top=false}%
}%
\def\POE@getwirepreset@l{%
  \setkeys[psset]{optexp}{%
    wirepresetout@=false,
    wirepresetout@top=false,
    wirepresetout@bottom=false}%
}%
\def\POE@getwirepreset@r{%
  \setkeys[psset]{optexp}{%
    wirepresetin@=false,
    wirepresetin@top=false,
    wirepresetin@bottom=false}%
}%
\let\POE@getwirepreset@i\POE@getwirepreset@l
\let\POE@getwirepreset@o\POE@getwirepreset@r
%    \end{macrocode}
%
% This code is for all components, fiber-optical and free-ray.
%    \begin{macrocode}
\define@choicekey*+[psset]{optexp}{wire@all}%
  [\val\nr]{false,none,true,all}[all]{%
  \ifcase\nr\relax
    \POE@getwire@none
  \or
    \POE@getwire@none
  \or
    \POE@getwire@all
  \or
    \POE@getwire@all
  \fi
}{%
  \ifx\@empty\val
    \POE@getwire@none
  \else
    \pst@expandafter\POE@psset@@wire{#1}\@empty,,\@nil
  \fi
}%
\def\POE@psset@@wire#1#2,#3,#4\@nil{%
  \POE@getwire@all
  \ifx\@empty#3\@empty
    \@nameuse{POE@getwire@#1}%
    \@nameuse{POE@getwire@#2}%
  \fi
}%
\def\POE@getwire@none{%
  \setkeys[psset]{optexp}{%
    wirein@=false, wireout@=false,
    wirein@top=false, wirein@bottom=false, 
    wireout@top=false, wireout@bottom=false}%
}%
\def\POE@getwire@all{%
  \setkeys[psset]{optexp}{%
    wirein@, wireout@,
    wirein@top, wirein@bottom, 
    wireout@top, wireout@bottom}%
}%
\def\POE@getwire@t{%
  \setkeys[psset]{optexp}{%
    wirein@bottom=false, wireout@bottom=false}%
}%
\def\POE@getwire@b{%
  \setkeys[psset]{optexp}{%
    wirein@top=false, wireout@top=false}%
}%
\def\POE@getwire@l{%
  \setkeys[psset]{optexp}{%
    wireout@=false, wireout@top=false, wireout@bottom=false}%
}%
\def\POE@getwire@r{%
  \setkeys[psset]{optexp}{%
    wirein@=false, wirein@top=false, wirein@bottom=false}%
}%
\let\POE@getwire@i\POE@getwire@l
\let\POE@getwire@o\POE@getwire@r
%    \end{macrocode}
% These are the internal boolkeys for the wire choices done with \opt{wirein},
% \opt{wireout} and \opt{wire}. Do not use them directly.
%    \begin{macrocode}
\define@boolkey[psset]{optexp}[POE@]{wirein@}[true]{}
\define@boolkey[psset]{optexp}[POE@]{wirein@top}[true]{}
\define@boolkey[psset]{optexp}[POE@]{wirein@bottom}[true]{}
\define@boolkey[psset]{optexp}[POE@]{wireout@}[true]{}
\define@boolkey[psset]{optexp}[POE@]{wireout@top}[true]{}
\define@boolkey[psset]{optexp}[POE@]{wireout@bottom}[true]{}
\define@boolkey[psset]{optexp}[POE@]{wirepresetin@}[true]{}
\define@boolkey[psset]{optexp}[POE@]{wirepresetin@top}[true]{}
\define@boolkey[psset]{optexp}[POE@]{wirepresetin@bottom}[true]{}
\define@boolkey[psset]{optexp}[POE@]{wirepresetout@}[true]{}
\define@boolkey[psset]{optexp}[POE@]{wirepresetout@top}[true]{}
\define@boolkey[psset]{optexp}[POE@]{wirepresetout@bottom}[true]{}
\psset[optexp]{wire=*all}%
\define@key[psset]{optexp}{wireangleA}{%
  \pst@checknum{#1}\POE@key@wireangleA
}%
\define@key[psset]{optexp}{wireangleB}{%
  \pst@checknum{#1}\POE@key@wireangleB
}%
\define@choicekey+[psset]{optexp}{wirealign}%
  [\val\nr]{rel,abs,relative,center,absolute}%
  {%
    \ifcase\nr\relax
      \let\POE@key@wirealign\POE@str@relative
    \or
      \let\POE@key@wirealign\POE@str@absolute
    \else
      \def\POE@key@wirealign{#1}%
    \fi
  }%
  {\PackageError{pst-optexp}{Unknown value '\val' for wirealign}}%
\define@key[psset]{optexp}{wirestyle}{%
  \@ifundefined{nc#1}%
    {\PackageError{pst-optexp}{Unknown value '#1' for wirestyle}}%
    {\def\POE@key@wirestyle{#1}}}
\psset[optexp]{%
  wireangleA=0,
  wireangleB=0,
  wirealign=relative,
  wirestyle=angle
}%
%    \end{macrocode}
% Which nodes to take for the automatic fiber and wire connections.
%    \begin{macrocode}
\define@key[psset]{optexp}{startnode}{\edef\POE@key@startnode{#1}}%
\define@key[psset]{optexp}{stopnode}{\edef\POE@key@stopnode{#1}}%
\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}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\drawwire}
%    \begin{macrocode}
\def\drawwire{\drawwire@{Wire}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\drawwire@}
%    \begin{macrocode}
\def\drawwire@#1{%
  \def\POE@setconnparam{%
    \let\POE@key@connangleA\POE@key@wireangleA
    \let\POE@key@connangleB\POE@key@wireangleB
    \let\POE@key@connalign\POE@key@wirealign
    \let\POE@key@connstyle\POE@key@wirestyle
  }%
  \drawconn@{#1}
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\drawfiber@}
%    \begin{macrocode}
\def\drawfiber@#1{%
  \def\POE@setconnparam{%
    \let\POE@key@connangleA\POE@key@fiberangleA
    \let\POE@key@connangleB\POE@key@fiberangleB
    \let\POE@key@connalign\POE@key@fiberalign
    \let\POE@key@connstyle\POE@key@fiberstyle
  }%
  \drawconn@{#1}%
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\drawconn@}
%    \begin{macrocode}
\def\drawconn@#1{%
  \ifPst@custom\else
    \def\pst@par{style=#1}%
  \fi
  \@ifnextchar[%]
    {\drawconn@i}{\drawconn@i[]}}%
\def\drawconn@i[#1]{%
  \addafter@par{#1}%
  \POE@normalizecomps\drawconn@ii}
\def\drawconn@ii{%
  \@ifnextchar\bgroup
    {\drawconn@iii}%
    {}}%
\def\drawconn@iii#1{%
  \def\POE@tempe{#1}\drawconn@iv}%
\def\drawconn@iv{%
  \@ifnextchar\bgroup{\drawconn@v}{}}%
\def\drawconn@v#1{%
  \expandafter\drawconn@vi\expandafter{\POE@tempe}{#1}%
  \def\POE@tempe{#1}\drawconn@iv}%
\def\drawconn@vi#1#2{%
  \begingroup
    \let\psk@angleA\relax
    \let\psk@angleB\relax
    \use@par
    \POE@setconnparam
    \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@connalign\POE@str@absolute
          \psset{angleA=\POE@key@connangleA}%
        \else
          \psset{angleA=! \POE@dict{%
            \POE@tempb \POE@tempa \POE@comps exch 
            \POE@key@connalign\space RelConnAngle
            \POE@key@connangleA\space add }
          }%
        \fi
      \fi
      \ifx\POE@angleB\relax
        \ifx\POE@key@connalign\POE@str@absolute
          \psset{angleB=\POE@key@connangleB}%
        \else
          \psset{angleB=! \POE@dict{%
            \POE@tempa \POE@tempb \POE@comps 
            \POE@key@connalign\space RelConnAngle
            \POE@key@connangleB\space add}
          }%
        \fi
      \fi
      \@nameuse{nc\POE@key@connstyle}{@@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
     /startinsidecount \POE@key@startinsidecount\space cvi def
     startinsidecount 0 eq {
       /beaminsidefirst false def
       /startinside false def
     } {
       /beaminsidefirst \ifPOE@beaminsidefirst true \else false \fi def
       /startinside \ifPOE@startinside true \else false \fi def
     } ifelse
     /stopinsidecount \POE@key@stopinsidecount\space cvi def
     stopinsidecount 0 eq {
       /beaminsidelast false def
       /stopinside false def
     } {
       /beaminsidelast \ifPOE@beaminsidelast true \else false \fi def
       /stopinside \ifPOE@stopinside true \else false \fi def
     } ifelse
     /beaminside \ifPOE@beaminside true \else false \fi def
     /connectifc \ifPOE@raytrace false \else true \fi def
     /beamalign 
       \ifx\POE@key@beamalign\POE@str@absolute\space 
         absolute
       \else\ifx\POE@key@beamalign\POE@str@relative\space
         relative
       \else
         firstcomp
       \fi\fi def
     /beampathskip \POE@key@beampathskip\space def
     \POE@key@beampathcount\space dup -1 gt { beampathskip add } if /beampathcount ED
     /useNA \ifPOE@useNA true \else false \fi def
     /aligntovector \ifx\POE@key@beamnodealign\POE@str@vector true \else false \fi def
     /beamdiffractionorder 
       \ifx\POE@key@beamdiffractionorder\@empty null 
       \else\POE@key@beamdiffractionorder\space 
       \fi def
     /beammode 
       \ifx\POE@key@beammode\POE@str@reflective
         refl
       \else\ifx\POE@key@beammode\POE@str@transmittive
         trans
       \else
         auto
       \fi\fi def
  }%
  \let\tx@Line\POE@tx@Line
}%
%    \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{%
  \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{%
  \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
%    \end{macrocode}
% Get the beamproperties from the first component if it is a source.
%    \begin{macrocode}
    \POE@HandleSourceBeam
%    \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}
    \addto@pscode{%
      {/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
      beamangle
      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
    20 dict begin
      DrawbeamPrepare
%    \end{macrocode}
% If there are only three elements or less on the stack, the first ray
% misses the next interface or is even parallel to the input interface.
%    \begin{macrocode}
      counttomark 3 gt { 
%    \end{macrocode}
% Define some parameters for Drawbeam which are based on TeX-parameters
%    \begin{macrocode}
        \ifx\psk@arrowA\arrowType@H
          \pst@number\pshooklength
        \else
          \psk@arrowsize\space CLW mul add dup \psk@arrowlength\space mul exch \psk@arrowinset mul neg add  
        \fi
        /arrowlength exch def 
        /arrowminlength \POE@key@ArrowInsideMinLength\space\pst@number\psunit mul def
        /arrowmaxlength \POE@key@ArrowInsideMaxLength\space\pst@number\psunit mul def
        /arrowpos  \psk@ArrowInsidePos\space def
        /arrowno   \psk@ArrowInsideNo\space cvi def
        /ArrowPosStart \psk@ArrowInsideOffset\space def
        /dArrowPosStart \psk@ArrowInsidePos\space def
        counttomark 3 idiv /N exch def
        (\psk@ArrowInside) length 0 gt {
          DrawbeamArrowInside
        }{
          DrawbeamSimple
        } ifelse
      } if
      cleartomark
    end
    \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 }%
%    \end{macrocode}
% Get the beamproperties from the first component if it is a source.
%    \begin{macrocode}
  \POE@HandleSourceBeam
  \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{%
    beamangle dup
    beamdiv 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
%    \end{macrocode}
% if \opt{beamwidth} is defined at Postscript level, it was defined from the source object.
%    \begin{macrocode}
      currentdict /beamwidth known {
        beamwidth currentdict /beamwidth undef
      } {
        mark \POE@key@beamwidth\space counttomark 0 eq { 0 } if exch pop
      } ifelse 0.5 mul
      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{macro}{\tx@Drawbeam}
%    \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}
% \end{macro}
%
% \begin{macro}{\POE@getcomprange}
%    \begin{macrocode}
\def\POE@getcomprange#1-#2\@nil{%
  \ifx\\#2\\%
    \ifx\\#1\\%
%    \end{macrocode}
% empty option, use the current component ID
%    \begin{macrocode}
      \@tempcnta=\POE@cnt
      \@tempcntb=\POE@cnt
    \else
%    \end{macrocode}
% A single number was given
%    \begin{macrocode}
      \@tempcnta=#1
      \@tempcntb=#1
%    \end{macrocode}
% Check if the number is valid, otherwise quit with an error.
%    \begin{macrocode}
      \ifodd
        \ifnum 0<\@tempcnta\ifnum\@tempcntb>\the\POE@cnt \@ne\else\z@\fi\else\@ne\fi
        \PackageError{pst-optexp}%
          {Component ID \the\@tempcnta\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\\%
      \@tempcnta=\@ne
    \else
      \@tempcnta=#1
    \fi
    \edef\POE@temp{\POE@getfirstchar#2\@nil}%
    \expandafter\ifx\POE@temp<\relax
      \POE@getlastcompprev#2%
    \else
      \POE@getlastcomp#2%
    \fi
    \POE@checkandfixcomprange
  \fi
}%
\def\POE@getcomprangeprev<#1-#2\@nil{%
  \@tempcnta=\POE@cnt
  \@tempcntb=\POE@cnt
  \ifx\\#1\\%
    \advance\@tempcnta by -1
  \else
    \advance\@tempcnta by -#1
  \fi
  \ifx\\#2\\\else
    \edef\POE@temp{\POE@getfirstchar#2\@nil}%
    \expandafter\ifx\POE@temp<\relax
      \POE@getlastcompprev#2%
    \else
      \POE@getlastcomp#2%
    \fi
  \fi
  \POE@checkandfixcomprange
}%
\def\POE@checkandfixcomprange{%
  \ifnum\@tempcnta>\POE@cnt
    \ifnum\@tempcntb>\POE@cnt
      \PackageError{pst-optexp}%
        {All components \the\@tempcnta-\the\@tempcntb\space out of range}%
    \fi
  \fi
  \ifnum\@tempcnta<\@ne
    \PackageWarning{pst-optexp}%
      {Component ID \the\@tempcnta\space is not valid, setting to 1.}%
    \@tempcnta=\@ne
  \else\ifnum\@tempcnta>\POE@cnt
    \PackageWarning{pst-optexp}%
      {A: Component ID \the\@tempcnta\space is not valid, setting to \MessageBreak
       the last defined value (\the\POE@cnt).}%
    \@tempcnta=\POE@cnt
  \fi\fi
  \ifnum\@tempcntb>\POE@cnt
    \PackageWarning{pst-optexp}%
      {B: Component ID \the\@tempcntb\space is not valid, setting to \MessageBreak
       the last defined value (\the\POE@cnt).}%
    \@tempcntb=\POE@cnt
  \else\ifnum\@tempcntb<\@ne
    \PackageWarning{pst-optexp}%
      {Component ID \the\@tempcntb\space is not valid, setting to 1.}%
    \@tempcntb=\@ne
  \fi\fi
}%
\def\POE@getlastcomp#1-{%
  \ifx\\#1\\%
    \ifnum\@tempcnta>\POE@cnt
      \PackageError{pst-optexp}{All components \the\@tempcnta- out of range.}%
    \fi%
    \@tempcntb=\POE@cnt
  \else
    \@tempcntb=#1\relax
  \fi
}%
\def\POE@getlastcompprev<#1-{%
  \@tempcntb=\POE@cnt
  \ifx\\#1\\%
    \advance\@tempcntb by -1
  \else
    \advance\@tempcntb by -#1
  \fi
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\POE@getcomps}
%    \begin{macrocode}
\def\POE@getcomps#1#2{%
  \def\POE@aftercomps{\addto@pscode{#1 \POE@comps }#2}%
  \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@getfirstchar#1#2\@nil{#1}%
\def\POE@getprevcompid<#1\@nil{%
  \ifx\\#1\\%
    \number\numexpr\POE@cnt-1\relax
  \else
    \number\numpexp\POE@cnt-#1\relax
  \fi
}%    
\def\POE@getcomps@iii#1{%
  \edef\POE@temp{\POE@getfirstchar#1{}\@nil}%
  \ifx\POE@temp\@empty
    \POE@getcomp{(\oenode{}{})}%
  \else\expandafter\ifx\POE@temp(\relax%)
    \POE@getplanenode#1%
  \else\ifnum9<1\POE@temp\relax
    \expandafter\POE@getcomprange#1-\@nil
    \POE@getcomp{%
      (\POE@str@basicname@prefix\POE@str@basicname@default)
      \the\@tempcnta\space\the\@tempcntb\space GetCompRange %
    }%
  \else\expandafter\ifx\POE@temp<\relax
    \expandafter\POE@getcomprangeprev#1-\@nil
    \POE@getcomp{%
      (\POE@str@basicname@prefix\POE@str@basicname@default)
      \the\@tempcnta\space\the\@tempcntb\space GetCompRange %
    }%
  \else\expandafter\ifx\POE@temp-\relax
    \POE@getcomprange#1-\@nil
    \POE@getcomp{%
      (\POE@str@basicname@prefix\POE@str@basicname@default) 
      \the\@tempcnta\space\the\@tempcntb\space GetCompRange %
    }%
  \else
    \POE@checkcompname{#1}%
    \POE@getcomp{(\oenode{}{#1})}%
  \fi\fi\fi\fi\fi%
  \POE@getcomps@i%
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\POE@getplanenode}
%    \begin{macrocode}
\def\POE@getplanenode(#1){%
  \pst@@getcoor{#1}%
  \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)
  }%
}%
\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}
% \begin{macro}{\POE@normalizecomps}
%   Expands all component parameters by resolving the ranges, i.e. {1-3}
%   becomes {1}{2}{3}. Nodes are wrapped with brackets, if necessary:
%   (1,1) becomes {(1,1)}.
%    \begin{macrocode}
\def\POE@normalizecomps#1{%
  \def\POE@aftercomps{\expandafter#1\POE@comps}%
  \def\POE@comps{}%
  \POE@normalizecomps@i%
}%
\def\POE@normalizecomps@i{%
  \@ifnextchar(%)
    {\POE@normalizecomps@ii}%
    {\POE@normalizecomps@iii}
}%
\def\POE@normalizecomps@ii(#1){%
  \edef\POE@comps{\POE@comps{(#1)}}%
  \POE@normalizecomps@i
}%
\def\POE@normalizecomps@iii{%
  \@ifnextchar\bgroup{\POE@normalizecomps@iv}{\POE@aftercomps}%
}%
%    \end{macrocode}
%
% Analyze the content of the comp id and expand it accordingly.
%    \begin{macrocode}
\def\POE@normalizecomps@iv#1{%
  \edef\POE@temp{\POE@getfirstchar#1{}\@nil}%
  \let\POE@tempb\POE@getcomprange
  \ifnum9<1\POE@temp\relax
    \def\POE@tempa{1}%
  \else\expandafter\ifx\POE@temp-\relax
    \def\POE@tempa{1}%
  \else\expandafter\ifx\POE@temp<\relax
    \def\POE@tempa{1}%
    \let\POE@tempb\POE@getcomprangeprev
  \else
    \def\POE@tempa{0}%
  \fi\fi\fi
  \ifodd\POE@tempa
    \POE@tempb#1-\@nil
    \ifnum\@tempcnta<\@tempcntb \def\POE@rel{<}\def\POE@inc{\@ne}%
    \else \def\POE@rel{>}\def\POE@inc{\m@ne}\fi
    \advance\@tempcntb\POE@inc
    \whiledo{\@tempcnta\POE@rel\@tempcntb}{%
      \edef\POE@comps{\POE@comps{\the\@tempcnta}}%
      \advance\@tempcnta\POE@inc
    }%
  \else
    \edef\POE@comps{\POE@comps{#1}}%
  \fi
  \POE@normalizecomps@i%
}%
%    \end{macrocode}
% \end{macro}
% 
% \subsection{Automatic connections}
%
% \begin{macro}{\POE@PresetWireConn}
% Draw automatic wires for electrical components.
%    \begin{macrocode}
\def\POE@PresetWireConn{%
  \ifPOE@startbox\else
    \ifPOE@wirepresetin@
      \drawwire@{WireIn}(\oenodeRefA{}){}
    \else\ifPOE@fiberin@
      \drawfiber@{FiberIn}(\oenodeRefA{}){}
    \fi\fi
  \fi
  \ifPOE@endbox\else
    \ifPOE@wirepresetout@
      \drawwire@{WireOut}{}(\oenodeRefB{})
    \else\ifPOE@fiberout@
      \drawfiber@{FiberOut}{}(\oenodeRefB{})
    \fi\fi
  \fi
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\POE@PresetFiberConn}
% Draw automatic fiber or wires for fiber components.
%    \begin{macrocode}
\def\POE@PresetFiberConn{%
  \ifPOE@startbox\else
    \ifPOE@fiberpresetin@
      \drawfiber@{FiberIn}(\oenodeRefA{}){}
    \else\ifPOE@wirein@
      \drawwire@{WireIn}(\oenodeRefA{}){}
    \fi\fi
  \fi
  \ifPOE@endbox\else
    \ifPOE@fiberpresetout@
      \drawfiber@{FiberOut}{}(\oenodeRefB{})
    \else\ifPOE@wireout@
      \drawwire@{WireOut}{}(\oenodeRefB{})
    \fi\fi
  \fi
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\POE@InternalConn}
%    \begin{macrocode}
\def\POE@InternalConn{%
  \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@startbox\else
      \ifPOE@fiberin@
        \drawfiber@{FiberIn}(\oenodeRefA{}){}
      \else\ifPOE@wirein@
        \drawwire@{WireIn}(\oenodeRefA{}){}
      \fi\fi
    \fi
    \ifPOE@endbox\else
      \ifPOE@fiberout@
        \drawfiber@{FiberOut}{}(\oenodeRefB{})
      \else\ifPOE@wireout@
        \drawwire@{WireOut}{}(\oenodeRefB{})
      \fi\fi
    \fi
  \fi
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\POE@usefiberorwirestyle}
%    \begin{macrocode}
\def\POE@usefiberorwirestyle{%
  \ifPOE@usefiberstyle
    \psset{style=Fiber, arrows=-, ArrowInside=-}%
  \else\ifPOE@usewirestyle
    \psset{style=Wire, arrows=-, ArrowInside=-}%
  \fi\fi
}%
%    \end{macrocode}
% \end{macro}
% 
% \section{Accessing component nodes} 
% \begin{macro}{\POE@checkcompname}
% Check if a component with name \#1 was already defined.
%    \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}{\oenode}
% Get the full node name of the node \#1 defined in component \#2.
%    \begin{macrocode}
\def\oenode#1#2{%
  \POE@str@basicname@prefix%
  \ifx\\#2\\%
    \POE@str@basicname@default\the\POE@cnt
  \else
    \ifnum9<1#2
      \POE@str@basicname@default
      #2%
    \else
      \POE@prevnode#2\@nil
      \POE@str@basicname@sep%
    \fi%
  \fi%
  #1%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{POE@prevnode}
%    \begin{macrocode}
\def\POE@prevnode#1#2\@nil{%
  \ifx<#1%
    \POE@str@basicname@default
    \ifx\\#2\\%
      \number\numexpr\POE@cnt-1\relax
    \else
      \number\numexpr\POE@cnt-#2\relax
    \fi
  \else
    #1#2%
  \fi
}%
%    \end{macrocode}
% \end{macro}
%
% Define some special nodes, which should be accessed always via these macros.
%
% \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}
%   The last (output) node of the component
%    \begin{macrocode}
\def\oenodeOut#1{\oenode{N}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenodeCenter}
%   The center node of the component.
%    \begin{macrocode}
\def\oenodeCenter#1{\oenode{Center}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenodeLabel}
%   The transformed label node of the component
%    \begin{macrocode}
\def\oenodeLabel#1{\oenode{Label}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenodeRefA}
%   The first reference node which is used for positioning of the
%   component. For dipoles it is equivalent to the (\#1) node.
%    \begin{macrocode}
\def\oenodeRefA#1{\oenode{A}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenodeRefB}
%   The second reference node, for dipoles it is equivalent to the (\#2)
%   node.
%    \begin{macrocode}
\def\oenodeRefB#1{\oenode{B}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenodeRotref}
%   The rotation reference node.
%    \begin{macrocode}
\def\oenodeRotref#1{\oenode{Rotref}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenodeTrefA}
%   The transformed first reference node, after applying parameters
%   \opt{compshift}, \opt{compoffset} and \opt{angle}.
%    \begin{macrocode}
\def\oenodeTrefA#1{\oenode{TrefA}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenodeTrefB}
%   The transformed second reference node.
%    \begin{macrocode}
\def\oenodeTrefB#1{\oenode{TrefB}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenode@RefA}
%   The first reference node, after it was projected on the reflection
%   plane of a tripole, at distance 1 from the center.
%    \begin{macrocode}
\def\oenode@RefA#1{\oenode{@A}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenode@RefB}
%   The second referencen node, projected on the reflection plane.
%    \begin{macrocode}
\def\oenode@RefB#1{\oenode{@B}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenode@TrefA}
%   The transformed, projected first reference node.
%    \begin{macrocode}
\def\oenode@TrefA#1{\oenode{@TrefA}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenode@TrefB}
%   The transformed, projected second reference node.
%    \begin{macrocode}
\def\oenode@TrefB#1{\oenode{@TrefB}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenode@Origin}
%   The origin of the component, available only for tripoles. Introduced
%   to be able to compute the angle between AO and BO at later times
%   (for \cs{rightangleprism} and \cs{optprism}.
%    \begin{macrocode}
\def\oenode@Origin#1{\oenode{Origin}{#1}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{oenode@Path}
% Use this macro for internal use with \cs{pssavepath}.
%    \begin{macrocode}
\def\oenode@Path#1{\oenode{Path@#1}{}}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\oenodeIfc}
%   The node of the interface no. \#1 of component \#2. Only integer
%   number, N or C are allowed. You should always use this e.g. to
%   access coupler nodes.
%    \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}
%   The end point of the last beam path which was saved with number \#1
%   (default is 1).
%    \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}
%   The upper end point of the last wide beam path saved with number \#1
%   (default is 1).
%    \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}
%   The lower end point of the last wide beam path saved with number \#1
%   (default is 1).
%    \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{macro}{\POE@beamvec}
%   Generic macro to load the Postscript coordinates of the direction
%   vector of the last beam segment (upper, lower, single, specified
%   with \#1) saved with number \#2.
%    \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}}%
\def\oeBeamVecMedian#1{%
  \oeBeamVecUp{#1} \oeBeamVecLow{#1} \POE@dict{VecAdd NormalizeVec}
}%
\def\oeBeamCenter#1{%
  \psGetNodeCenter{\oenodeBeamUp{#1}} \oenodeBeamUp{#1}.x \oenodeBeamUp{#1}.y
  \psGetNodeCenter{\oenodeBeamLow{#1}} \oenodeBeamLow{#1}.x \oenodeBeamLow{#1}.y
  \POE@dict{VecAdd 0.5 VecScale}
}%
%    \end{macrocode}
% \end{macro}
% 
% \section{Components}
%
% \begin{macro}{\POE@useifccode}
% \begin{macro}{\begin@CompIfc}
%    \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}
% \end{macro}
% \end{macro}
% \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}{\newOptexpFiberComp}
%    \begin{macrocode}
\def\newOptexpFiberComp#1{%
  \POE@Verb{%
    \tx@NodeScale
    [ #1 (\oenode{}{}) {\tx@ScreenCoor}
      NewOptexpFiberComp
  }%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{newOptexpElecComp}
% This may change at later times.
%    \begin{macrocode}
\let\newOptexpElecComp\newOptexpFiberComp
%    \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}{\POE@SaveBeamParameters}
%   Save the current beam parameters. This is used to be able to set a
%   source beam with the usual beam parameters.
%    \begin{macrocode}
\def\POE@SaveBeamParameters{%
  \let\POE@tempA\POE@key@beamangle
  \let\POE@tempB\POE@key@beamdiv
  \let\POE@tempC\POE@key@beamwidth
  \let\POE@tempD\POE@key@beamalign
  \let\POE@key@beamangle\relax
  \let\POE@key@beamdiv\relax
  \let\POE@key@beamwidth\relax
  \let\POE@key@beamalign\relax
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\POE@SetSourceAndRestoreBeamParameters}
%    \begin{macrocode}
\def\POE@SetSourceAndRestoreBeamParameters{%
  \let\POE@key@sourcebeamangle\POE@key@beamangle
  \let\POE@key@sourcebeamdiv\POE@key@beamdiv
  \let\POE@key@sourcebeamwidth\POE@key@beamwidth
  \let\POE@key@sourcebeamalign\POE@key@beamalign
  \let\POE@key@beamangle\POE@tempA
  \let\POE@key@beamdiv\POE@tempB
  \let\POE@key@beamwidth\POE@tempC
  \let\POE@key@beamalign\POE@tempD
}%      
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\POE@HandleSourceBeam}
%   Load beam properties from the first component on the stack, if it is
%   an optical source. Also handle the beamalign=firstcomp case, since
%   this also depends on the first component.
%    \begin{macrocode}
\def\POE@HandleSourceBeam{%
  \addto@pscode{%
    counttomark 0 eq not {
      dup cvn load dup /source known { 
        /source get { def } forall
      }{ pop } ifelse
    } if
%    \end{macrocode}
% Handle the beamalign=firstcomp case. Calculate the angle of the first
% component's reference line and set the beamalign parameter to
% absolute.
%    \begin{macrocode}
    beamalign firstcomp eq {
      dup dup (Center) NodeName tx@NodeDict exch known not {
%    \end{macrocode}
% If we have no node called \opt{\ldots Center}, the first object isn't
% a component, but a node. Switch to relative alignment.
%    \begin{macrocode}
        pop /beamalign relative def
      } {
        RelConnAngle@tref exch atan /beamangle exch def
        /beamalign absolute def
      } ifelse
    } if
  }%
}%
%    \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 }%
    \POE@SaveBeamParameters
    \use@par
    \POE@SetSourceAndRestoreBeamParameters
%    \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{}}%
    }%
    \def\tx@Line{Line }%
}%
%    \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{}}%
  }%
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\POE@unsetbeamparameters}
% Unset some beam parameters which might be used by \cs{optsource}.
%    \begin{macrocode}
\def\POE@unsetbeamparameters{%
  \let\POE@key@beamangle\relax
  \let\POE@key@beamdiv\relax
  \let\POE@key@beamwidth\relax
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\end@OptexpObj}
%    \begin{macrocode}
\def\end@OptexpObj{%
  \ifnum9<1\POE@key@compname\else
    \POE@Verb{
      (\oenode{}{\POE@key@compname})
      (\oenode{}{\the\POE@cnt}) CompAlias }%
  \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}{\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{%
  \@ifnextchar\bgroup
    {\POE@newdipole@i[#1]{#2}}{\POE@newdipole@i[#1]{#2}{}}%
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\POE@newdipole@i}
%    \begin{macrocode}
\def\POE@newdipole@i[#1]#2#3{%
  \@ifundefined{#2@i}{%
    \@namedef{#2}{\pst@object{#2}}%
    \expandafter\def\csname #2@i\endcsname(##1)(##2){%
      \@ifnextchar\bgroup%
        {\@nameuse{#2@ii}(##1)(##2)}%
        {\@nameuse{#2@ii}(##1)(##2){}}%
    }%
    \expandafter\def\csname #2@ii\endcsname(##1)(##2)##3{%
      \addbefore@par{#3}%
      \addafter@par{#1}%
      \begin@OptexpObj
        \ifPOE@backlayer
          \POE@regNodes{##1}{##2}
        \fi
        \POE@drawcomponent{#2}{##3}
        \ifPOE@backlayer
          \POE@Verb{ (1) (N) (\oenode{}{}) CorrectDipoleIfc }%
          \@ifundefined{#2@conn}{\POE@InternalConn}{\@nameuse{#2@conn}}%
        \fi
      \end@OptexpDipole
    }%
    \@ifundefined{#2@nodes}{\expandafter\def\csname #2@nodes\endcsname{\POE@dipole@nodes}}{}%
  }{%
    \PackageError{pst-optexp}{%
      dipole component '#2' already defined}%
  }%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\POE@newfiberdipole}
%    \begin{macrocode}
\def\POE@newfiberdipole[#1]#2{%
  \@ifnextchar\bgroup
    {\POE@newfiberdipole@i[#1]{#2}}{\POE@newfiberdipole@i[#1]{#2}{}}%
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\POE@newfiberdipole@i}
%    \begin{macrocode}
\def\POE@newfiberdipole@i[#1]#2#3{%
  \@ifundefined{#2@i}{%
    \@namedef{#2}{\pst@object{#2}}%
    \expandafter\def\csname #2@i\endcsname(##1)(##2){%
      \@ifnextchar\bgroup%
        {\@nameuse{#2@ii}(##1)(##2)}%
        {\@nameuse{#2@ii}(##1)(##2){}}%
    }%
    \expandafter\def\csname #2@ii\endcsname(##1)(##2)##3{%
      \addbefore@par{#3}%
      \addafter@par{#1}%
      \begin@OptexpObj
        \ifPOE@backlayer
          \POE@regNodes{##1}{##2}
        \fi
        \POE@drawcomponent{#2}{##3}
        \ifPOE@backlayer
          \POE@Verb{ (1) (N) (\oenode{}{}) CorrectDipoleIfc }%
          \POE@PresetFiberConn
        \fi
        \end@OptexpDipole
      }%
      \@ifundefined{#2@nodes}{\expandafter\def\csname #2@nodes\endcsname{\POE@fiberdipole@nodes}}{}%
   }{%
     \PackageError{pst-optexp}{%
       fiber dipole object '#2' already defined}%
  }%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\POE@newtripole}
%    \begin{macrocode}
\def\POE@newtripole[#1]#2{%
  \@ifnextchar\bgroup
    {\POE@newtripole@i[#1]{#2}}{\POE@newtripole@i[#1]{#2}{}}%
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\POE@newtripole@i}
%    \begin{macrocode}
\def\POE@newtripole@i[#1]#2#3{%
  \@ifundefined{#2@i}{%
    \@namedef{#2}{\pst@object{#2}}%
    \expandafter\def\csname #2@i\endcsname(##1)(##2)(##3){%
      \@ifnextchar\bgroup{\@nameuse{#2@ii}(##1)(##2)(##3)}%
                         {\@nameuse{#2@ii}(##1)(##2)(##3){}}%
    }%
    \expandafter\def\csname #2@ii\endcsname(##1)(##2)(##3)##4{%
      \addbefore@par{#3}%
      \addafter@par{ref@angle=0,#1}%
      \begin@OptexpTripole
        \ifPOE@backlayer
          \POE@calcNodes{##1}{##2}{##3}%
          \POE@regNodes{##1}{##3}%
        \fi
        \POE@drawcomponent{#2}{##4}
        \ifPOE@backlayer
          \POE@InternalConn
        \fi
      \end@OptexpTripole
    }%
    \@ifundefined{#2@nodes}{\expandafter\def\csname #2@nodes\endcsname{\POE@tripole@nodes}}{}%
  }{%
    \PackageError{pst-optexp}{%
      tripole object '#2' already defined}%
  }%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\optaom}
%    \begin{macrocode}
\def\optaom{\pst@object{optaom}}%
\def\optaom@i(#1)(#2)(#3){%
  \@ifnextchar\bgroup
    {\optaom@ii(#1)(#2)(#3)}%
    {\optaom@ii(#1)(#2)(#3){}}%
}%
\def\optaom@ii(#1)(#2)(#3)#4{%
  \addafter@par{ref@angle=180}%
  \begin@OptexpTripole
    \ifPOE@backlayer
      \ifx\POE@key@abspos\@empty
        \ifx\POE@key@position\@empty
          \psLNode(#1)(#2){0.5}{\oenode{Tmp}{}}
        \else
          \psLNode(#1)(#2){\POE@key@position}{\oenode{Tmp}{}}
        \fi
      \else
        \psLDNode(#1)(#2){\POE@key@abspos}{\oenode{Tmp}{}}
      \fi
      \POE@calcNodes{#1}{\oenode{Tmp}{}}{#3}%
      \POE@regNodes{#1}{#3}
    \fi
    \POE@drawcomponent{optaom}{#4}
    \ifPOE@backlayer
      \POE@InternalConn
    \fi
  \end@OptexpTripole
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\optcoupler}
%    \begin{macrocode}
\def\optcoupler{\pst@object{optcoupler}}%
\def\optcoupler@i(#1)(#2){%
  \@ifnextchar(%)
    {\optcoupler@ii(#1)(#2)}%
    {\optcoupler@ii(#1)(#1)(#2)(#2)}%
}%
\def\optcoupler@ii(#1)(#2)(#3)(#4){%
  \@ifnextchar\bgroup%
    {\optcoupler@iii(#1)(#2)(#3)(#4)}%
    {\optcoupler@iii(#1)(#2)(#3)(#4){}}%
}%
\def\optcoupler@iii(#1)(#2)(#3)(#4)#5{%
  \begin@OptexpObj
    \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}
    \ifPOE@backlayer
      \POE@Verb{%
        (1) (3) (\oenode{}{}) CorrectDipoleIfc 
        (2) (4) (\oenode{}{}) CorrectDipoleIfc 
      }%
      \ifPOE@fiberpresetin@
        \ifPOE@fiberpresetin@top
          \drawfiber@{FiberIn1}[stopnode=1](#1){}
        \fi
        \ifPOE@fiberpresetin@bottom
          \drawfiber@{FiberIn2}[stopnode=2](#2){}
        \fi
      \fi
      \ifPOE@fiberpresetout@
        \ifPOE@fiberpresetout@top
          \drawfiber@{FiberOut1}[startnode=3]{}(#3)
        \fi
        \ifPOE@fiberpresetout@bottom
          \drawfiber@{FiberOut2}[startnode=N]{}(#4)
        \fi
      \fi
    \fi
  \end@OptexpObj
}%
%    \end{macrocode}
% \end{macro}
% 
% 
% \begin{macro}{\wdmsplitter}
%    \begin{macrocode}
\def\wdmsplitter{\pst@object{wdmsplitter}}%
\def\wdmsplitter@i{%
  \def\my@aftercoors{\wdmsplitter@ii}%
  \POE@couplernodecount=0\relax
  \def\coupler@coors{}%
  \coupler@@getcoors
}
\def\wdmsplitter@ii{%
  \@ifnextchar\bgroup%
    {\wdmsplitter@iii}%
    {\wdmsplitter@iii{}}%
}%
\def\wdmsplitter@iii#1{%
  \ifnum\POE@couplernodecount>1\else
    \PackageError{pst-optexp}%
    {A wdmsplitter expects at least two nodes, one input and one output node}%
  \fi
  \begin@OptexpObj
    \ifPOE@backlayer
%    \end{macrocode}
% Use first coordinate pair as RefA
%    \begin{macrocode}
      \pnode(! [ \coupler@coors 1 \POE@dict{GetCoordinatePair} \tx@UserCoor){\oenodeRefA{}}
      \ifx\POE@key@coupleralign\POE@str@top
%    \end{macrocode}
% For top alignment, use first output coordinate pair, i.e. second coordinate pair as RefB
%    \begin{macrocode}
        \pnode(! [ \coupler@coors 2 \POE@dict{GetCoordinatePair} \tx@UserCoor){\oenodeRefB{}}
      \else\ifx\POE@key@coupleralign\POE@str@bottom
%    \end{macrocode}
% For bottom alignment, use last output coordinate pair
%    \begin{macrocode}
        \pnode(! [ \coupler@coors counttomark 2 idiv \POE@dict{GetCoordinatePair} \tx@UserCoor){\oenodeRefB{}}
      \else
%    \end{macrocode}
% Use median of all output coordinate pairs as RefB
%    \begin{macrocode}
        \pnode(! [ \coupler@coors
%    \end{macrocode}
% remove input node from stack
%    \begin{macrocode}
pop pop
%    \end{macrocode}
% count number of output coordinate pair, keep that number and save it behind the mark
%    \begin{macrocode}
counttomark 2 idiv dup counttomark 1 add 1 roll
1 sub { \POE@dict{VecAdd} } repeat
%    \end{macrocode}
% divide by number of output coordinate pairs and remove mark
%    \begin{macrocode}
4 -1 roll 1 exch div \POE@dict{VecScale} 3 -1 roll pop \tx@UserCoor){\oenodeRefB{}}
      \fi\fi
    \fi
    \POE@drawcomponent{wdmsplitter}{#1}
    \ifPOE@backlayer
      \POE@Verb{%
        2 1 \the\POE@couplernodecount\space
        {
          inttostr (1) exch (\oenode{}{}) CorrectDipoleIfc
        } for
      }%
      \ifPOE@fiberpresetin@
        \drawfiber@{FiberIn}[stopnode=1](! [ \coupler@coors 1 \POE@dict{GetCoordinatePair} \tx@UserCoor){}
      \fi
      \ifPOE@fiberpresetout@
        \ifPOE@fiberpresetout@top
          \drawfiber@{FiberOut1}[startnode=2]{}(! [ \coupler@coors 2 \POE@dict{GetCoordinatePair} \tx@UserCoor)
        \fi
        \ifPOE@fiberpresetout@bottom
          \drawfiber@{FiberOut2}[startnode=N]{}(! [ \coupler@coors \the\POE@couplernodecount\space \POE@dict{GetCoordinatePair} \tx@UserCoor)
        \fi
      \fi
%    \end{macrocode}
% If top and bottom fibers are drawn, we must also draw all other output fibers
%    \begin{macrocode}
        \ifPOE@fiberpresetout@top\ifPOE@fiberpresetout@bottom
          \@tempcnta=\POE@couplernodecount
          \advance\@tempcnta by -3
          \ifnum0<\@tempcnta
            \multido{\i=3+1}{\the\@tempcnta}{%
              \drawfiber@{FiberOut}[startnode=\i]{}(! [ \coupler@coors \i\space \POE@dict{GetCoordinatePair} \tx@UserCoor)
            }%
          \fi
        \fi\fi  
    \fi
  \end@OptexpObj
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\wdmcoupler}
%    \begin{macrocode}
\def\wdmcoupler{\pst@object{wdmcoupler}}%
\def\wdmcoupler@i{%
  \def\my@aftercoors{%
%    \end{macrocode}
% Subtract one, because we counted all nodes. However, we can always access the last
% node by N, so we more often use the second last, i.e the last input node
%    \begin{macrocode}
    \advance\POE@couplernodecount by -1\relax%
    \wdmcoupler@ii}%
  \POE@couplernodecount=0\relax
  \def\coupler@coors{}%
  \coupler@@getcoors
}
%    \end{macrocode}
% \begin{macro}{\coupler@@getcoors}
%   Read in a variable number of node coordinates. The coordinates are saved in \cs{coupler@coors},
%   their number in \cs{POE@couplernodecount}.
%    \begin{macrocode}
\def\coupler@@getcoors(#1){%
  \advance\POE@couplernodecount by \@ne\relax%
  \pst@@getcoor{#1}%
  \edef\coupler@coors{\pst@coor\coupler@coors}%
  \@ifnextchar({\coupler@@getcoors}{\my@aftercoors}%
}
%    \end{macrocode}
% \end{macro}
%    \begin{macrocode}
\def\wdmcoupler@ii{%
  \@ifnextchar\bgroup%
    {\wdmcoupler@iii}%
    {\wdmcoupler@iii{}}%
  }%
\def\wdmcoupler@iii#1{%
  \ifnum\POE@couplernodecount>0\else
    \PackageError{pst-optexp}%
    {A wdmcoupler expects at least two nodes, one input and one output node}%
  \fi
  \begin@OptexpObj
    \ifPOE@backlayer
%    \end{macrocode}
% Use last coordinate pair as RefB
%    \begin{macrocode}
      \pnode(! [ \coupler@coors \the\POE@couplernodecount\space 1 add \POE@dict{GetCoordinatePair} \tx@UserCoor){\oenodeRefB{}}
      \ifx\POE@key@coupleralign\POE@str@top
%    \end{macrocode}
% For top alignment, use first coordinate pair as RefA
%    \begin{macrocode}
         \pnode(! [ \coupler@coors \POE@dict{GetFirstInputCoordinatePair} \tx@UserCoor){\oenodeRefA{}}
      \else\ifx\POE@key@coupleralign\POE@str@bottom
%    \end{macrocode}
% For bottom alignment, use second last coordinate pair as RefA
%    \begin{macrocode}
         \pnode(! [ \coupler@coors \POE@dict{GetLastInputCoordinatePair} \tx@UserCoor){\oenodeRefA{}}
      \else
%    \end{macrocode}
% Use median of all input coordinate pairs as RefA
%    \begin{macrocode}
        \pnode(! [ \coupler@coors
%    \end{macrocode}
% remove output node from stack
%    \begin{macrocode}
counttomark -2 roll pop pop
%    \end{macrocode}
% count number of input coordinate pair, keep that number and save it behind the mark
%    \begin{macrocode}
counttomark 2 idiv dup counttomark 1 add 1 roll
1 sub { \POE@dict{VecAdd} } repeat
%    \end{macrocode}
% divide by number of input coordinate pairs and remove mark
%    \begin{macrocode}
4 -1 roll 1 exch div \POE@dict{VecScale} 3 -1 roll pop \tx@UserCoor){\oenodeRefA{}}
      \fi\fi
    \fi
    \POE@drawcomponent{wdmcoupler}{#1}
    \ifPOE@backlayer 
      \POE@Verb{%
        1 1 \the\POE@couplernodecount\space
        {
          inttostr \the\POE@couplernodecount\space 1 add inttostr (\oenode{}{}) CorrectDipoleIfc
        } for
      }%
      \ifPOE@fiberpresetout@
        \drawfiber@{FiberOut}[startnode=N]{}(\oenodeRefB{})
      \fi
      \ifPOE@fiberpresetin@
        \ifPOE@fiberpresetin@top
          \drawfiber@{FiberIn1}[stopnode=1](! [ \coupler@coors 1 \POE@dict{GetCoordinatePair} \tx@UserCoor){}
        \fi 
        \ifPOE@fiberpresetin@bottom
          \drawfiber@{FiberIn2}[stopnode=\the\POE@couplernodecount](! [ \coupler@coors \the\POE@couplernodecount\space \POE@dict{GetCoordinatePair} \tx@UserCoor){}
        \fi
%    \end{macrocode}
% If top and bottom fibers are drawn, we must also draw all other input fibers
%    \begin{macrocode}
        \ifPOE@fiberpresetin@top\ifPOE@fiberpresetin@bottom
          \@tempcnta=\POE@couplernodecount
          \advance\@tempcnta by -2
          \ifnum0<\@tempcnta
            \multido{\i=2+1}{\the\@tempcnta}{%
              \drawfiber@{FiberIn}[stopnode=\i](! [ \coupler@coors \i\space \POE@dict{GetCoordinatePair} \tx@UserCoor){}
            }%
          \fi
        \fi\fi
      \fi
    \fi
  \end@OptexpObj
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\optcirculator}
%    \begin{macrocode}
\def\optcirculator{\pst@object{optcirculator}}%
\def\optcirculator@i(#1)(#2)(#3){%
  \@ifnextchar\bgroup%
    {\optcirculator@ii(#1)(#2)(#3)}%
    {\optcirculator@ii(#1)(#2)(#3){}}%
}%
\def\POE@calcCircRefNodes#1#2#3{%
\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
}%
\def\optcirculator@ii(#1)(#2)(#3)#4{%
  \addafter@par{ref@angle=0}%
  \begin@OptexpObj
    \POE@calcCircRefNodes{#1}{#2}{#3}%
    \POE@drawcomponent{optcirculator}{#4}
    \ifPOE@backlayer
      \ifPOE@fiberpresetin@top
        \drawfiber@{FiberIn}[stopnode=1](#1){}
      \fi
      \ifPOE@fiberpresetout@
        \ifPOE@fiberpresetout@top
          \drawfiber@{FiberOut1}[startnode=N]{}(#2)
        \fi
        \ifPOE@fiberpresetout@bottom
          \drawfiber@{FiberOut2}[startnode=2, fiberalign=center]{}(#3)
        \fi
      \fi
    \fi
  \end@OptexpObj
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\fiberbox}
%    \begin{macrocode}
\def\fiberbox{\pst@object{fiberbox}}%
\def\fiberbox@i(#1)(#2){%
  \@ifnextchar(%)
    {\fiberbox@ii(#1)(#2)}%
    {\fiberbox@ii(#1)(#2)()()}%
}%
\def\fiberbox@ii(#1)(#2)(#3)(#4){%
  \@ifnextchar\bgroup%
    {\fiberbox@iii(#1)(#2)(#3)(#4)}%
    {\fiberbox@iii(#1)(#2)(#3)(#4){}}%
}%
\def\fiberbox@iii(#1)(#2)(#3)(#4)#5{%
  \begin@OptexpObj
    \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@regNodes@
        \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}
    \ifPOE@backlayer
      \ifx\\#3#4\\%
%    \end{macrocode}
% Connect only, if the fiberbox has a single related interface node.
%    \begin{macrocode}
        \ifnum\POE@key@fiberboxcountin=1
          \ifPOE@fiberpresetin@
            \drawfiber@{FiberIn}(#1){}
          \else\ifPOE@wirein@
            \drawwire@{WireIn}(#1){}
          \fi\fi
        \fi
        \ifnum\POE@key@fiberboxcountout=1
          \ifPOE@fiberpresetout@
            \drawfiber@{FiberOut}{}(#2)
          \else\ifPOE@wireout@
            \drawwire@{WireOut}{}(#2)
          \fi\fi
        \fi
      \else
%    \end{macrocode}
% If four reference nodes are specified, connect all of them with the respective interface
% nodes they are aligned to.
%    \begin{macrocode}
        \ifPOE@fiberpresetin@top
          \drawfiber@{FiberIn1}(#1){}
        \else\ifPOE@wirein@top
          \drawwire@{WireIn1}(#1){}
        \fi\fi
        \ifPOE@fiberpresetin@bottom
          \drawfiber@{FiberIn2}(#2){}
        \else\ifPOE@wirein@bottom
          \drawwire@{WireIn2}(#2){}
        \fi\fi
        \ifPOE@fiberpresetout@top
          \drawfiber@{FiberOut1}{}(#3)
        \else\ifPOE@wireout@top
          \drawwire@{WireOut1}{}(#3)
        \fi\fi
        \ifPOE@fiberpresetout@bottom
          \drawfiber@{FiberOut2}{}(#4)
        \else\ifPOE@wireout@bottom
          \drawwire@{WireOut2}{}(#4)
        \fi\fi
      \fi
    \fi
  \end@OptexpObj
}%
%    \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 /exch@ref@\oenode{}{} ED
    X@A Y@A}){\oenode@RefA{}}%
  \pnode(! \POE@dict{X@B Y@B}){\oenode@RefB{}}%
  \pnode(#2){\oenode@Origin{}}%
}\ignorespaces}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\POE@calcAngle}
%   Calculate the angle between the vectors A->O and B->0, which is
%   needed by \cs{rightangleprism} and \cs{optprism}. Also calculate the
%   angle difference between 'Winkelhalbierende' and
%   'Seitenhalbierende', which is required for some corrections in
%   \cs{rightangleprism}.
%    \begin{macrocode}
\def\POE@calcAngle{%
  \POE@Verb{%
    gsave
      STV CP T
      /N@\oenode@Origin{} @GetCenter 2 copy
      /N@\oenodeRefA{} @GetCenter VecSub /ay ED /ax ED
      /N@\oenodeRefB{} @GetCenter VecSub /by ED /bx ED
%    \end{macrocode}
% Winkelhalbierende (cx, cy)
%    \begin{macrocode}
      ax ay NormalizeVec bx by NormalizeVec VecAdd 
      2 copy Pyth abs 1e-4 lt {
%    \end{macrocode}
% vectors a and b are antiparallel
%    \begin{macrocode}
        pop pop
        ax ay 90 matrix rotate dtransform
      } if
      NormalizeVec 2 copy
%    \end{macrocode}
% Seitenhalbierende
%    \begin{macrocode}
      ax ay bx by VecAdd 
      2 copy Pyth abs 1e-4 lt {
%    \end{macrocode}
% vectors a and b are parallel
%    \begin{macrocode}
        pop pop ax ay
      } if
      NormalizeVec 
      4 copy 4 copy
      DotProd Acos 5 1 roll Chirality mul 
      /dOEangle exch def
      ax ay Pyth bx by Pyth
      2 copy dup mul exch dup mul add
      ax bx sub ay by sub Pyth dup mul exch sub
      3 1 roll -2 mul mul div Acos /OEangle exch def
%    \end{macrocode}
% project vector (ax, by) on the normal to the bisector
%    \begin{macrocode}
      neg exch ax ay \tx@UserCoor DotProd abs /@myht exch def
    grestore
  }%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\POE@saveDiffractionNodes}
%    \begin{macrocode}
\def\POE@saveDiffractionNodes{%
  \POE@Verb{%
    gsave
      STV CP T 
      /N@\oenodeRefA{} @GetCenter
      /N@\oenode@Origin{} @GetCenter @ABVect exch atan /myangle ED
      /N@\oenode@Origin{} @GetCenter
      /N@\oenodeRefB{} @GetCenter @ABDist /mydist ED    
    grestore
  }%
  \pnode(! \POE@dict{mydist myangle 180 sub} PtoC \tx@UserCoor){\oenode{DO0}{}}%
  \multido{\i=1+1}{\POE@key@diffractionorders}{%
    \pnode(! \POE@dict{mydist myangle 180 sub 180 OEangle sub \i\space mul } add PtoC \tx@UserCoor){\oenode{DO\i}{}}%
    \pnode(! \POE@dict{mydist myangle 180 sub 180 OEangle sub \i\space mul } sub PtoC \tx@UserCoor){\oenode{DO-\i}{}}%
  }%
\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@regNodes@
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\POE@regNodes@}
% Some additional work which needs to be done in \cs{POE@regNodes}, but must be
% called separately in some cases (e.g. \cs{fiberbox}).
%    \begin{macrocode}
\def\POE@regNodes@{%
  \POE@Verb{%
    /@xref [\POE@key@extnode@xrefs] def
    /@yref [\POE@key@extnode@yrefs] def
    /@@ang 
    \ifx\POE@key@innercompalign\POE@str@absolute
      /N@\POE@refnodeA\space /N@\POE@refnodeB\space SlopeAngle
    \else
      0
    \fi def
  }%
  \ifx\POE@key@extnodealign\POE@str@absolute
    \POE@Verb{%
      /N@\POE@refnodeA\space @GetCenter /N@\POE@refnodeB\space @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@dict{
    /N@#2 @GetCenter \POE@temp 
    #4 \POE@key@labelrefangle\space add matrix rotate dtransform 
    VecAdd \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{}}%
     \psrotate(\oenodeRotref{}){!\POE@key@angle}{%
       #1%
       \POE@pnode@shiftedrot(0,\POE@key@labeloffset)%
                            {\oenodeCenter{}}%
                            {\oenodeLabel{}}%
                            {\POE@key@labelangle}%
     }%
   }%
}%
%    \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@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@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@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{asphericlens}
\newOptexpDipole{pinhole}
\newOptexpDipole{crystal}
\newOptexpDipole{polarization}
\newOptexpDipole{optbox}
\newOptexpDipole{optsource}{position=start}
\newOptexpDipole{optplate}
\newOptexpDipole{optretplate}
\newOptexpDipole{optdetector}{position=end}
\newOptexpDipole{optdiode}{allowbeaminside=false}
\newOptexpDipole{doveprism}
\newOptexpDipole{glanthompson}
\newOptexpDipole{parabolicmirror}{position=end, ref@angle=-90}
\newOptexpDipole{axicon}
\newOptexpDipole{optwedge}
%    \end{macrocode}
% 
% Define all free-ray tripoles
%    \begin{macrocode}
\newOptexpTripole{mirror}
\newOptexpTripole[ref@angle=45]{beamsplitter}
\newOptexpTripole{optgrating}
\newOptexpTripole[ref@angle=90]{transmissiongrating}
\newOptexpTripole[ref@angle=45]{pentaprism}
\newOptexpTripole[ref@angle=45]{rightangleprism}
\newOptexpTripole[ref@angle=45]{optprism}
\newOptexpTripole{oapmirror}
%    \end{macrocode}
%
% \begin{macro}{\optdipole}
%    \begin{macrocode}
\def\optdipole{\pst@object{optdipole}}
\def\optdipole@i(#1)(#2){%
  \@ifnextchar\bgroup%
    {\optdipole@iii(#1)(#2)}%
    {\optdipole@ii(#1)(#2)}%
}%
\def\optdipole@ii(#1)(#2){%
  \optdipole@v(#1)(#2){}{}%
}%
\def\optdipole@iii(#1)(#2)#3{%
  \@ifnextchar\bgroup%
    {\optdipole@iv(#1)(#2){#3}}%
    {\optdipole@v(#1)(#2){#3}}%
}%
\def\optdipole@iv(#1)(#2)#3#4{%
   \addbefore@par{innercompalign=relative}%
   \begin@OptexpObj
      \ifPOE@backlayer
        \POE@regNodes{#1}{#2}%
      \fi
      \def\optdipole@comp{\psrotate(0,0){!\POE@dict{@@ang}}{#3}}%
      \POE@drawcomponent{optdipole}{#4}%
      \ifPOE@backlayer
        \POE@InternalConn
      \fi
   \end@OptexpObj
}%
%    \end{macrocode}
% Only one argument given, decide if this is supposed to be the label,
% or the component.
%    \begin{macrocode}
\def\optdipole@v(#1)(#2)#3{%
   \addbefore@par{innercompalign=relative}%
   \begin@OptexpObj
      \ifPOE@backlayer
        \POE@regNodes{#1}{#2}
      \fi
      \ifx\POE@key@optdipolecomp\@empty
        \def\optdipole@comp{\psrotate(0,0){!\POE@dict{@@ang}}{#3}}%
        \POE@drawcomponent{optdipole}{}
      \else
        \def\optdipole@comp{\psrotate(0,0){!\POE@dict{@@ang}}{\POE@key@optdipolecomp}}%
        \POE@drawcomponent{optdipole}{#3}
      \fi
      \ifPOE@backlayer
        \POE@InternalConn
      \fi
   \end@OptexpObj
}%
\def\optdipole@nodes{\POE@dipole@nodes}
%    \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){%
  \@ifnextchar\bgroup
    {\opttripole@iii(#1)(#2)(#3)}%
    {\opttripole@ii(#1)(#2)(#3)}%
}%
\def\opttripole@ii(#1)(#2)(#3){%
  \opttripole@v(#1)(#2)(#3){}{}%
}%
\def\opttripole@iii(#1)(#2)(#3)#4{%
  \@ifnextchar\bgroup
    {\opttripole@iv(#1)(#2)(#3){#4}}%
    {\opttripole@v(#1)(#2)(#3){#4}}%
}%
\def\opttripole@iv(#1)(#2)(#3)#4#5{%
  \addafter@par{ref@angle=0}
  \begin@OptexpTripole
    \ifPOE@backlayer   
      \POE@calcNodes{#1}{#2}{#3}%
      \POE@regNodes{#1}{#3}%
    \fi
    \def\opttripole@comp{#4}%
    \POE@drawcomponent{opttripole}{#5}
    \ifPOE@backlayer
      \POE@InternalConn
    \fi
  \end@OptexpTripole
}%
%    \end{macrocode}
% Only one argument given, decide if this is supposed to be the label, or the component
%    \begin{macrocode}
\def\opttripole@v(#1)(#2)(#3)#4{%
  \addafter@par{ref@angle=0}
  \begin@OptexpTripole
    \ifPOE@backlayer   
      \POE@calcNodes{#1}{#2}{#3}%
      \POE@regNodes{#1}{#3}%
    \fi
    \ifx\POE@key@opttripolecomp\@empty
      \def\opttripole@comp{#3}%
      \POE@drawcomponent{opttripole}{}%
    \else
      \def\opttripole@comp{\POE@key@opttripolecomp}%
      \POE@drawcomponent{opttripole}{#4}%
    \fi
    \ifPOE@backlayer
      \POE@InternalConn
    \fi
  \end@OptexpTripole
}%
\def\opttripole@nodes{\POE@tripole@nodes}
%    \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@OptexpObj
    \ifPOE@backlayer
      \POE@regNodes{\POE@tempa}{\POE@tempb}%
    \fi
    \POE@drawcomponent{fibercollimator}{#1}
    \ifPOE@backlayer
      \ifPOE@beam
        \drawbeam(\oenodeRefA{}){}
      \fi
      \ifPOE@fiberpresetout@
        \ifx\@empty\POE@tempc
          \drawfiber{}(\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
  \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#1#2{%
  \def\POE@comp{%
    \ifPOE@backlayer
      \pnode(!\POE@dict{@@x0 @@y0}){\oenodeCenter{}}
      \@nameuse{#1@nodes}
    \fi
    \ifPOE@frontlayer
      \@nameuse{#1@comp}
    \fi
    \ifx\POE@key@extnode\@empty\else
      \ifPOE@backlayer
        \multido{\i=1+1}{\POE@key@extnode@cnt}{%
          \pnode(! \POE@dict{
            @xref \i\space 1 sub get 
            @yref \i\space 1 sub get
            DefineExtNode}){\oenode{Ext\i}{}}%
          \pnode(\oenode{Ext1}{}){\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
  }%
  \@ifundefined{#1@ref}{}{\@nameuse{#1@ref}}%
  \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@showinterfaces
    \ifPOE@frontlayer
      \POE@drawinterfaces[style=IfcStyle]
    \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@drawinterfaces}
%    \begin{macrocode}
\def\POE@drawinterfaces{\pst@object{POE@drawinterfaces}}
\def\POE@drawinterfaces@i{%
  \begin@OpenObj%
  \addto@pscode{%
    \psk@dotsize
    \@nameuse{psds@\psk@dotstyle}
    \pst@optexpdict
    /\oenode{}{} load begin
      1 1 N {
        IfcName load begin
          X Y
          CompMtrx transform CM itransform 2 copy
          currentdict /RX known { 0 0 }{ DX DY } ifelse
          CompMtrx dtransform CM idtransform 2 copy
          NAlow 0 eq NAup 0 eq and { 
            -0.5 VecScale 4 2 roll 0.5 VecScale
          } {
            \tx@UserCoor NAlow VecScale 4 2 roll \tx@UserCoor NAup VecScale
          } ifelse
        end
        8 -2 roll VecAdd moveto VecAdd lineto
      } for
    end end }%
  \pst@stroke
  \use@pscode
  \end@OpenObj
}%
%    \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}{\POE@tripole@nodes}
%    \begin{macrocode}
\def\POE@tripole@nodes{%
  \newOptexpComp{{0 0} {1 0} @@x neg @@x refl {PlainIfc} 1}%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\POE@dipole@nodes}
%    \begin{macrocode}
\def\POE@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 }%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{POE@fiberdipole@nodes}
%    \begin{macrocode}
\def\POE@fiberdipole@nodes{%
  \newOptexpFiberComp{%
    {@@x0 @@x sub 0}
    @@x 0 eq not {
      {@@x0 @@x add 0}
    } if }%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
\let\POE@elecdipole@nodes\POE@fiberdipole@nodes
%    \end{macrocode}
%
% \begin{macro}{POE@comp@rectangle}
%    \begin{macrocode}
\def\POE@comp@rectangle{%
  \psframe[dimen=outer](!\POE@dict{@@x neg @@y0 @@y sub})%
                       (!\POE@dict{@@x @@y0 @@y add})%
}%
%    \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@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@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@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@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
  \pnode(0,0){\oenodeCenter{}}
}%
%    \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@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@extended
      \psframe[style=ExtendedMirror]%
        (! \@ht neg \POE@key@mirrordepth\space )%
        (! \@ht 0)
    \else\ifx\POE@key@mirrortype\POE@str@semitrans
      \psframe[style=SemitransMirror]%
        (! \@ht neg \POE@key@mirrordepth\space )%
        (! \@ht 0)
    \fi\fi\fi
    \ifx\POE@key@mirrortype\POE@str@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@extended 1
      \else\ifx\POE@key@mirrortype\POE@str@semitrans 1
      \else 0
      \fi\fi
%    \end{macrocode}
% extended or semitrans mirrortype
%    \begin{macrocode}
      \bgroup
      \ifx\POE@key@mirrortype\POE@str@extended
        \psset{style=ExtendedMirror}
      \else\ifx\POE@key@mirrortype\POE@str@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{parabolicmirror}
%
% \begin{macro}{\parabolicmirror@nodes}
%    \begin{macrocode}
\def\parabolicmirror@nodes{%
  \pssavepath[linestyle=none, arrows=-,ArrowInside=-]{\oenode@Path{A}}{%
    \parametricplot[algebraic, VarStep, VarStepEpsilon=1e-7, plotstyle=cspline]%
      {0}{\POE@key@parmirrorheight\space 0.5 mul}%
      {-\POE@key@parmirrorwidth/(0.25*\POE@key@parmirrorheight^2)*t^2|-t}}
  \pssavepath[linestyle=none, arrows=-,ArrowInside=-]{\oenode@Path{B}}{%
    \parametricplot[algebraic, VarStep, VarStepEpsilon=1e-7, plotstyle=cspline]%
      {0}{\POE@key@parmirrorheight\space 0.5 mul}%
      {-\POE@key@parmirrorwidth/(0.25*\POE@key@parmirrorheight^2)*t^2|t}}
  \newOptexpComp{%
    {-\POE@key@parmirrorwidth\space 0.16 mul \POE@key@parmirrorheight\space -0.2 mul} 
      tx@IntersectDict /\PIT@name{\oenode@Path{A}} get 0 0 refl {PathIfc}
    {0 0} {1 0} 0 0 trans {PlainIfc}
    {-\POE@key@parmirrorwidth\space 0.16 mul \POE@key@parmirrorheight\space 0.2 mul}
      tx@IntersectDict /\PIT@name{\oenode@Path{B}} get 0 0 refl {PathIfc}
    1 }%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\parabolicmirror@comp}
%    \begin{macrocode}
\def\parabolicmirror@comp{%
  \pstracecurve{\oenode@Path{A}}
  \pstracecurve{\oenode@Path{B}}
\ignorespaces}
%    \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{Aspheric lens}
%
% \begin{macro}{\asphericlens@nodes}
%    \begin{macrocode}
\def\asphericlens@nodes{%
  \def\POE@asphere##1{%
    (##1)^2*(1/(\POE@key@asphereradiusleft*(1+sqrt(1-(1+\POE@key@asphereconstant)*(##1)^2/\POE@key@asphereradiusleft^2)))+%
    (##1)^2*(\POE@key@asphereAfour % 
      + (##1)^2*(\POE@key@asphereAsix %
        + ((##1)^2*(\POE@key@asphereAeight %
          + \POE@key@asphereAten*(##1)^2)))))}%
  \def\POE@arcright##1{%
    (##1)^2/(\POE@key@asphereradiusright*sqrt(1-(##1)^2/\POE@key@asphereradiusright^2))}%
  \POE@Verb{%
    tx@Dict begin 
      /POEasphereleftx0 (\POE@asphere{0.5*\POE@key@asphereheight}) AlgParser cvx exec def
      /POEasphererightx0
      \ifdim\POE@key@asphereradiusright pt>0pt
        (\POE@arcright{0.5*\POE@key@asphereheight}) AlgParser cvx exec
      \else
        0
      \fi
      def
      \POE@key@aspherewidth\space POEasphereleftx0 POEasphererightx0 add sub dup 0 gt {
        POEasphererightx0 add /POEasphererightx0 exch def
      } {
        pop
      } ifelse
    end
  }%
  \pssavepath[linestyle=none, arrows=-,ArrowInside=-]{\oenode@Path{A}}{%
    \psparametricplot[algebraic, plotstyle=cspline]%
      {\POE@key@asphereheight\space -0.5 mul}%
      {\POE@key@asphereheight\space 0.5 mul}%
      {\POE@asphere{t}-POEasphereleftx0|t}}%
  \ifdim\POE@key@asphereradiusright pt>0pt
    \pssavepath[linestyle=none, arrows=-,ArrowInside=-]{\oenode@Path{B}}{%
      \psparametricplot[algebraic, plotstyle=cspline]%
        {\POE@key@asphereheight\space 0.5 mul}%
        {\POE@key@asphereheight\space -0.5 mul}%
        {-\POE@arcright{t}+POEasphererightx0|t}}%
  \fi
  \newOptexpComp{%
    {POEasphereleftx0 neg 0} tx@IntersectDict /\PIT@name{\oenode@Path{A}} get 0 0 trans {PathIfc}
    {POEasphererightx0 0}
    \ifdim\POE@key@asphereradiusright pt>0pt
      tx@IntersectDict /\PIT@name{\oenode@Path{B}} get 0 0 trans {PathIfc}
    \else
      {0 1} 0 0 trans {PlainIfc}
    \fi
    \POE@key@n }%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\asphericlens@comp}
%    \begin{macrocode}
\def\asphericlens@comp{%
  \pscustom[arrows=-]{%
    \pstracecurve{\oenode@Path{A}}%
    \ifdim\POE@key@asphereradiusright pt>0pt
      \pstracecurve{\oenode@Path{B}}
    \else
      \lineto(!POEasphererightx0 \POE@key@asphereheight\space 0.5 mul)
      \lineto(!POEasphererightx0 \POE@key@asphereheight\space -0.5 mul)
    \fi
    \closepath}%
}%
%    \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@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@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@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@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.16 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@parallel
    \psline[arrows=<->](! 0 \@sz neg)(! 0 \@sz)
  \fi
  \ifx\POE@key@poltype\POE@str@perp
    \psdot(0,0)
    \pscircle[fillstyle=none](0,0){0.12}
  \fi
  \ifx\POE@key@poltype\POE@str@misc
    \psline[arrows=<->](! 0 \@sz neg)(! 0 \@sz)
    \psdot(0,0)
    \pscircle[fillstyle=none](0,0){0.12}
  \fi
  \ifx\POE@key@poltype\POE@str@rcirc
    \psellipticarc[fillstyle=none, arrows=->]%
      (0,0)(! \@sz 2 div \@sz){20}{-20}
  \fi
  \ifx\POE@key@poltype\POE@str@lcirc
    \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@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@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{transmissiongrating}
%
% \begin{macro}{\transmissiongrating@ref}
%    \begin{macrocode}
\def\transmissiongrating@ref{%
  \POE@calcAngle
  \POE@setref{/@@x \POE@key@gratingwidth\space 0.5 mul def}%
  \edef\POE@key@angle{%
    \POE@dict{ exch@ref@\oenode{}{} { -90 }{ 90 } ifelse }
    \POE@key@angle\space add
  }%
  \POE@Verb{%
    @xref @yref
    exch@ref@\oenode{}{} { 
      [ exch { neg } forall ]
    } if
    /@xref ED
    exch@ref@\oenode{}{} { 
      [ exch { neg } forall ]
    } if
    /@yref ED
  }%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\transmissiongrating@nodes}
%    \begin{macrocode}
\def\transmissiongrating@nodes{%
  \newOptexpComp{%
    {0 0} {1 0} \POE@key@gratingwidth\space -0.5 mul dup neg 
    refltrans {PlainIfc} 1}%
}%
\let\transmissiongrating@comp\optgrating@comp
%    \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}
\let\optbox@comp\POE@comp@rectangle
%    \end{macrocode}
% \end{macro}
% 
% \subsubsection{optsource}
%
% \begin{macro}{\optsource@ref}
%    \begin{macrocode}
\def\optsource@ref{%
  \let\POE@key@optboxwidth\POE@key@sourcewidth
  \let\POE@key@optboxheight\POE@key@sourceheight
  \optbox@ref
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\optsource@nodes}
%    \begin{macrocode}
\def\optsource@nodes{%
  \POE@dipole@nodes
  \POE@Verb{%
    \oenode{}{} begin
    4 dict dup /source exch def begin
      \if\POE@key@sourcebeamangle\relax\else
        /beamangle \POE@key@sourcebeamangle\space def
      \fi
      \if\POE@key@sourcebeamdiv\relax\else
        /beamdiv \POE@key@sourcebeamdiv\space def
      \fi
      \if\POE@key@sourcebeamwidth\relax\else
        /beamwidth \POE@key@sourcebeamwidth\space def
      \fi
      \if\POE@key@sourcebeamalign\relax\else
        /beamalign \POE@key@sourcebeamalign\space def
      \fi
    end
    source length 0 eq { currentdict /source undef } if
    end }%
}%
%
% \begin{macro}{\optsource@comp}
%    \begin{macrocode}
\let\optsource@comp\POE@comp@rectangle
%    \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@round 0.5 mul\fi
      \space def
    }%
  \fi
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\optdetector@nodes}
%    \begin{macrocode}
\def\optdetector@nodes{%
  \POE@dipole@nodes
  \ifx\POE@key@dettype\POE@str@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@round
    \psellipticwedge(!\POE@dict{@@x0 @@x sub @@y0})%
      (!\POE@dict{@@x 2 mul @@y}){-90}{90}%
  \else\ifx\POE@key@dettype\POE@str@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
    \POE@comp@rectangle
    \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}
% 
% \begin{macro}{optdetector@conn}
%    \begin{macrocode}
\def\optdetector@conn{%
  \ifPOE@startbox\else
    \ifPOE@beam
      \drawbeam[raytrace=false](\oenodeRefA{}){}
    \else\ifPOE@fiberin@
      \drawfiber@{FiberIn}(\oenodeRefA{}){}
    \else\ifPOE@wirein@
      \drawwire@{WireIn}(\oenodeRefA{}){}
    \fi\fi\fi
  \fi
  \ifPOE@endbox\else
    \ifPOE@wirepresetout@
      \drawwire@{WireOut}{}(\oenodeRefB{})
    \else\ifPOE@fiberout@
      \drawfiber@{FiberOut}{}(\oenodeRefB{})
    \fi\fi
  \fi
}%
%    \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 dup /@@y ED /@@x ED 
    0.4 mul /@@sz ED
  }%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\optdiode@comp}
%    \begin{macrocode}
\def\optdiode@comp{%
   \POE@comp@rectangle
   \pspolygon(!\POE@dict{@@sz neg dup})
             (!\POE@dict{@@sz neg @@sz})
             (!\POE@dict{@@sz 0})
   \psline(!\POE@dict{@@sz \POE@clwh add @@sz})%
          (!\POE@dict{@@sz \POE@clwh add @@sz neg})
\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{%
   \pspolygon(!\POE@dict{@@x neg @@y neg})%
             (!\POE@dict{@@x @@y neg})%
             (!\POE@dict{@@x @@y 2 mul sub @@y})%
             (!\POE@dict{@@y 2 mul @@x sub @@y})
\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@ref}
%    \begin{macrocode}
\def\optprism@ref{%
  \POE@calcAngle
  \ifx\POE@key@prismtype\POE@str@reflective
    \edef\POE@key@labelrefangle{180}%
  \fi
}%
%    \end{macrocode}
% \end{macro}
%
% \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
  }%
  \begingroup
    \edef\POE@temp{\ifx\POE@key@prismtype\POE@str@reflective neg \fi}%
    \pnode(! 0 \@hshift neg){\oenodeCenter{}}%
    \newOptexpComp{%
      {\@sz -0.6 mul \@ang tan mul \@hshift neg} 
      {90 \@ang sub dup cos exch sin \POE@temp} 
      \@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 \POE@temp} 
      \@sz \@ang cos div dup -0.4 mul exch 0.6 mul trans {PlainIfc} 
%    \end{macrocode}
% Need to change the order of the two interfaces on the stack and add an
% additional interface.
%    \begin{macrocode}
      \ifx\POE@key@prismtype\POE@str@reflective
        12 6 roll
        {0 \@sz 0.4 mul \@hshift sub } 
        {1 0} \@ang tan \@sz mul dup neg exch refl {PlainIfc}
        12 6 roll
      \fi
      \POE@key@n true }%
  \endgroup
}%
%    \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
  }%
  \edef\POE@temp{\ifx\POE@key@prismtype\POE@str@reflective -1 mul \fi}%
  \pspolygon(! \@sz neg \@altan mul \@sz -0.4 mul \POE@temp \@hshift sub)
            (! \@sz \@altan mul \@sz -0.4 mul \POE@temp \@hshift sub)
            (! 0 \@sz 0.6 mul \POE@temp \@hshift sub)
}%
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{rightangleprism}
%
% \begin{macro}{\rightangleprism@ref}
%   All tripole components are aligned such, that the x-axis is normal
%   to the angle bisector (Winkelhalbierende), but for the right angle
%   prism the x-axis must be oriented normal to the bisector
%   (Seitenhalbierende). So we must correct for the difference in both
%   orientations, which is stored in dOEangle.
%    \begin{macrocode}
\def\rightangleprism@ref{%
  \POE@calcAngle
  \POE@Verb{%
    /@htA @myht def
    /@OEtrafo {dOEangle matrix rotate dtransform } bind def
  }%
%    \end{macrocode}
% Correct also the label reference angle for nonsymmetric reference nodes.
%    \begin{macrocode}
  \let\POE@temp\POE@key@labelrefangle
  \edef\POE@key@labelrefangle{\POE@temp \POE@dict{dOEangle add} }%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\rightangleprism@nodes}
%    \begin{macrocode}
\def\rightangleprism@nodes{%
  \edef\@sz{\POE@key@raprismsize\space 0.5 mul }%
  \POE@Verb{%
    \ifx\POE@key@raprismalign\POE@str@auto
      /@corrshift {} bind def
    \else
      /@corrshift {@htA sub \@sz 0.5 mul add } bind def%
    \fi
  }%
  \newOptexpComp{%
    {@htA neg @htA \@sz sub @corrshift @OEtrafo} {1 0 @OEtrafo} 
    @htA \@sz sub @htA trans {PlainIfc}
    {@htA neg 0 @corrshift @OEtrafo} {1 1 @OEtrafo} 
    @htA 2 sqrt mul dup \@sz 0.5 sqrt div sub exch refl {PlainIfc}
    {@htA 0 @corrshift @OEtrafo} {-1 1 @OEtrafo} 
    @htA 2 sqrt mul dup \@sz 0.5 sqrt div sub exch refl {PlainIfc}
    {@htA dup \@sz sub @corrshift @OEtrafo} {1 0 @OEtrafo} 
     @htA neg \@sz @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 }%
  \ifx\POE@key@raprismalign\POE@str@auto
    \pspolygon(!\POE@dict{\@sz neg @htA \@sz sub @OEtrafo})
              (!\POE@dict{\@sz @htA \@sz sub @OEtrafo})
              (! 0 \POE@dict{@htA @OEtrafo})%
  \else
    \pspolygon(!\POE@dict{\@sz \@sz -0.5 mul @OEtrafo})%
              (!\POE@dict{\@sz neg \@sz -0.5 mul @OEtrafo})%
              (!\POE@dict{0 \@sz 0.5 mul @OEtrafo})
  \fi
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{optaom}
%
% \begin{macro}{\optaom@ref}
%    \begin{macrocode}
\def\optaom@ref{%
  \POE@setref{/@@x \POE@key@aomwidth\space 0.5 mul def }%
  \POE@setref{/@@y \POE@key@aomheight\space 0.5 mul def }%
  \POE@calcAngle
  \ifx\POE@key@aomalign\POE@str@symmetric\else
    \edef\POE@key@angle{\POE@key@angle\space 180 \POE@dict{OEangle} sub 0.5 mul sub }%
  \fi
  \edef\POE@key@angle{\POE@key@angle\space 180 add }%
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\optaom@nodes}
%    \begin{macrocode}
\def\optaom@nodes{%
  \ifodd
    \ifx\POE@key@aomalign\POE@str@symmetric
      \ifx\POE@key@aomreflalign\POE@str@parallel 1\else 0\fi
    \else 0\fi
%    \end{macrocode}
%
% A 'parallel' reflection interface is possible only, if the aomalign is
% symmetric, because otherwise it is probable, that the incoming beam is
% parallel to that interface.
%    \begin{macrocode}
    \newOptexpCompAmb{%
      {@@x neg 0} {0 1} @@y neg @@y
      trans {PlainIfc}
      {0 0}
      \ifx\POE@key@aomalign\POE@str@symmetric
        {1 0}
      \else
        {1 0 180 OEangle sub 0.5 mul matrix rotate dtransform}
      \fi
      0 0 trans {PlainIfc}
      {@@x @@y} {0 1} @@y -2 mul 0
      trans {PlainIfc}
      {@@x @@y neg} {0 1} 0 @@y 2 mul
      trans {PlainIfc}
      2 1
    }%
  \else
    \newOptexpCompAmb{%
      {@@x neg 0} {0 1} @@y neg @@y trans {PlainIfc}
      {0 0}
      \ifx\POE@key@aomalign\POE@str@symmetric
        {0 1}
      \else
        {0 1 180 OEangle sub 0.5 mul matrix rotate dtransform}
      \fi
      0 0 refltrans {PlainIfc}
      {@@x @@y} {0 1} @@y -2 mul 0
      trans {PlainIfc}
      {@@x @@y neg} {0 1} 0 @@y 2 mul
      trans {PlainIfc}
      2 1
    }%
  \fi
  \POE@Verb{%
    gsave
      tx@Dict begin
        STV {CP T} stopped pop
      end
      (C) (\oenode{}{}) GetPlaneVec 2 copy
      /N@\oenodeRefA{} @GetCenter
      /N@\oenodeCenter{} @GetCenter 
      @ABVect 90 matrix rotate dtransform
      NormalVec ReflectVec ToVec dup
      \oenode{}{} begin
        {0 0} exch 0 0 refltrans name (C-1) {PlainIfc} {sc} NewCompIfc
        (C) (C1) IfcAlias
        2 1 \POE@key@diffractionorders\space {% vec i
          2 copy neg dup 5 string cvs (C) exch strcat % vec i vec -i (C-i)
              3 -1 roll exec 4 -1 roll % vec i (C-i) X Y -i
              1 add 180 OEangle sub 0.5 mul mul 
              matrix rotate dtransform ToVec % vec i (C-i) {X' Y'}
              {0 0} exch 0 0 refltrans name 7 -1 roll {PlainIfc} {sc} NewCompIfc
          2 copy 3 -1 roll 5 string cvs (C) exch strcat % vec i vec i (C-i)
              3 -1 roll exec 4 -1 roll % vec i (Ci) X Y i
              1 add 180 OEangle sub 0.5 mul mul 
              matrix rotate dtransform ToVec % vec i (Ci) {X' Y'}
              {0 0} exch 0 0 refltrans name 7 -1 roll {PlainIfc} {sc} NewCompIfc
            } for pop
        /grating true def
      end
    grestore 
  }%
  \POE@saveDiffractionNodes
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\optaom@comp}
%    \begin{macrocode}
\def\optaom@comp{%
  \POE@comp@rectangle
  \ifx\POE@key@aomcomp\POE@str@default
    \multido{\i=0+1}{\POE@key@aomgratingcount}{%
      \psrline(!\POE@dict{@@x -0.7 mul \POE@key@aomgratingcount\space 2 div dup 1.5 add 
                 @@y exch div exch 0.5 sub \i\space sub mul})%
              (!\POE@dict{@@x 1.4 mul 0})%
    }%
  \else
    \POE@key@aomcomp
  \fi
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \subsubsection{off-axis parabolic mirror}
%
% \begin{macro}{\oapmirror@nodes}
%    \begin{macrocode}
\def\oapmirror@nodes{%
  \POE@calcAngle
  \POE@Verb{%
    gsave
      STV CP T
      /N@\oenodeRefA{} @GetCenter 
      /N@\oenodeCenter{} @GetCenter
      @ABVect NormalizeVec 2 copy 
      90 matrix rotate dtransform
      /N@\oenodeRefB{} @GetCenter
      /N@\oenodeCenter{} @GetCenter @ABVect
      \tx@UserCoor 2 copy 6 2 roll 
    grestore
    DotProd tx@Dict begin /POEzonalradius ED end
    DotProd 
    % y = ax^2, a = 1/(2x_0^2) (-h + sqrt(h^2 + x_0^2)), x_0 = @zonalradius.
    tx@Dict begin 
    dup /POEoapheight ED neg dup dup mul POEzonalradius dup mul add sqrt add 0.5 POEzonalradius dup mul div mul
    dup /POEoappar ED
    /POEangle 180 OEangle sub 0.5 mul POEzonalradius 0 gt { -1 mul 180 add } if DegToRad def
    end
  }%
  \def\POE@tempX{((POEoappar*(t^2))-(0.25/POEoappar)+POEoapheight)}%
  \def\POE@tempY{(-t+POEzonalradius)}%
  \pssavepath[linestyle=none, arrows=-,ArrowInside=-]{\oenode@Path{A}}{%
    \psparametricplot[algebraic]%
      {POEzonalradius dup 0 gt {\POE@key@oapmirroraperture@outer}{\POE@key@oapmirroraperture@inner} ifelse add}%
      {POEzonalradius dup 0 gt {\POE@key@oapmirroraperture@inner}{\POE@key@oapmirroraperture@outer} ifelse sub}%
      {(cos(POEangle)*\POE@tempX+sin(POEangle)*\POE@tempY)|(cos(POEangle)*\POE@tempY-sin(POEangle)*\POE@tempX)}}%
  \newOptexpComp{%
    {0 0} tx@IntersectDict /\PIT@name{\oenode@Path{A}} get 0 0 refl {PathIfc}
    1 }%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\oapmirror@comp}
%    \begin{macrocode}
\def\oapmirror@comp{%
  \pstracecurve{\oenode@Path{A}}%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{Axicon}
%
% \begin{macro}{axicon@nodes}
%    \begin{macrocode}
\def\axicon@nodes{%
  \POE@setref{%
    /@@right \POE@key@axiconheight\space 0.5 mul \POE@key@axiconangle\space dup sin exch cos div mul def
    @@right \POE@key@axiconwidth\space max 0.5 mul /@@x exch def
    /@@y \POE@key@axiconheight\space 0.5 mul def
    /@@right 
  }%
  \pssavepath[linestyle=none, arrows=-,ArrowInside=-]{\oenode@Path{A}}{%
    \psline(!\POE@dict{@@x @@right sub @@y})
           (!\POE@dict{@@x 0})
           (!\POE@dict{@@x @@right sub @@y neg})
  }%
  \newOptexpComp{%
    {@@x neg 0} {0 1} @@y neg @@y trans {PlainIfc}
    {@@x 0}
      tx@IntersectDict /\PIT@name{\oenode@Path{A}} get 0 0 trans {PathIfc}
    \POE@key@n }%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{axicon@comp}
%    \begin{macrocode}
\def\axicon@comp{%
  \pspolygon[arrows=-]%
    (!\POE@dict{@@x neg @@y})(!\POE@dict{@@x @@right sub @@y})
    (!\POE@dict{@@x 0})(!\POE@dict{@@x @@right sub @@y neg})
    (!\POE@dict{@@x neg @@y neg})
    %(!\POE@key@axiconwidth\space neg \POE@key@axiconheight\space -0.5 mul)
    %(!\POE@key@axiconwidth\space neg \POE@key@axiconheight\space 0.5 mul)
    %(! 0 \POE@key@axiconheight\space 0.5 mul)
    %(! \POE@key@axiconheight\space 0.5 mul \POE@key@axiconangle\space tan mul 0)
    %(! 0 \POE@key@axiconheight\space -0.5 mul)
}%
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{optwedge}
%
% \begin{macro}{optwedge@nodes}
%    \begin{macrocode}
\def\optwedge@nodes{%
  \POE@Verb{%
    /@@xl \POE@key@wedgeheight\space \POE@key@wedgeangleleft\space tan mul def
    /@@xr \POE@key@wedgeheight\space \POE@key@wedgeangleright\space tan mul def
    /@@xa \POE@key@wedgewidth\space @@xl @@xr add sub dup 0 gt {0.5 mul}{pop 0} ifelse def
  }%
  \newOptexpComp{%
    {@@xl @@xa add -0.5 mul 0} {\POE@key@wedgeangleleft\space tan 1} 0 0 trans {PlainIfc}
    {@@xr @@xa add 0.5 mul 0} {\POE@key@wedgeangleright\space tan -1} 0 0 trans {PlainIfc}
  \POE@key@n }%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{optwedge@comp}
%    \begin{macrocode}
\def\optwedge@comp{%
  \pspolygon[arrows=-](!\POE@dict{@@xa} \POE@key@wedgeheight\space 0.5 mul)
                      (!\POE@dict{@@xa @@xr} add \POE@key@wedgeheight\space -0.5 mul)
                      (!\POE@dict{@@xa @@xl} add neg \POE@key@wedgeheight\space -0.5 mul)
                      (!\POE@dict{@@xa} neg \POE@key@wedgeheight\space 0.5 mul)
}%
%    \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{%
  \pscustom[style=Fiber, arrows=-]{%
    \multido{\i=0+1}{\POE@key@fiberloops}{%
      \parametricplot[liftpen=1, plotpoints=100]{0}{1}{%
        t 360 mul sin 1 t 360 mul cos sub
        \POE@key@fiberloopradius\space dup 3 1 roll mul 3 1 roll mul
        \POE@key@fiberloops\space 1 sub -2 div \i\space add
        \POE@key@fiberloopsep\space mul add exch
      }%
    }%
  }%
\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{%
  \POE@comp@rectangle
  \begingroup
    \POE@usefiberorwirestyle
    \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)%
  \endgroup
\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 
    \ifx\POE@key@innercompalign\POE@str@absolute\else
      /@@ang \POE@key@filterangle\space def
    \fi
  }%
}%
\let\optfilter@nodes\POE@dipole@nodes
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\optfilter@comp}
%    \begin{macrocode}
\def\optfilter@comp{%
  \def\POE@filter@curve{%
    \parametricplot[plotstyle=curve,arrows=-]{-1}{1}{%
      \POE@dict{@@x} dup t mul 0.7 mul exch t Pi mul RadtoDeg 
      90 add cos 0.2 mul mul}%
  }%
  \def\POE@strike@line{%
    \psline(!\POE@dict{@@x -0.3 mul @@y -0.15 mul})%
           (!\POE@dict{@@x 0.3 mul @@y 0.15 mul})
  }%
  \POE@comp@rectangle
  \psrotate(\oenodeCenter{}){!\POE@dict{@@ang}}{%
  \psset{style=FilterStyle}%
    \ifx\POE@key@filtertype\POE@str@bandpass
      \rput(!\POE@dict{0 @@x -0.5 mul}){\POE@strike@line\POE@filter@curve}
      \rput(0, 0){%
        \POE@usefiberorwirestyle
        \POE@filter@curve}
      \rput(!\POE@dict{0 @@x 0.5 mul}){\POE@strike@line\POE@filter@curve}
    \else\ifx\POE@key@filtertype\POE@str@bandstop
      \begingroup
        \POE@usefiberorwirestyle
        \rput(!\POE@dict{0 @@x -0.5 mul}){\POE@filter@curve}
        \rput(!\POE@dict{0 @@x 0.5 mul}){\POE@filter@curve}
      \endgroup
      \rput(0,0){\POE@strike@line\POE@filter@curve}
    \else\ifx\POE@key@filtertype\POE@str@lowpass
      \rput(!\POE@dict{0 @@x -0.5 mul}){%
        \POE@usefiberorwirestyle
        \POE@filter@curve}
        \rput(0, 0){\POE@strike@line\POE@filter@curve}
        \rput(!\POE@dict{0 @@x 0.5 mul}){\POE@strike@line\POE@filter@curve}
    \else\ifx\POE@key@filtertype\POE@str@highpass
      \rput(!\POE@dict{0 @@x 0.5 mul}){%
        \POE@usefiberorwirestyle
        \POE@filter@curve}
        \rput(0, 0){\POE@strike@line\POE@filter@curve}
        \rput(!\POE@dict{0 @@x -0.5 mul}){\POE@strike@line\POE@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{%
  \pspolygon(!\POE@dict{@@x 0})%
            (!\POE@dict{@@x neg @@y})%
            (!\POE@dict{@@x neg @@y neg})
}%
%    \end{macrocode}
% \end{macro} 
%
%\subsubsection{polcontrol}
%
% \begin{macro}{polcontrol@ref}
%    \begin{macrocode}
\def\polcontrol@ref{%
  \ifx\POE@key@polcontroltype\POE@str@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
    \POE@usefiberorwirestyle
    \ifx\POE@key@polcontroltype\POE@str@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{%
  \POE@comp@rectangle
  \psline[style=IsolatorArrow, arrows=->]%
    (!\POE@dict{@@x neg 0.6 mul 0})%
    (!\POE@dict{@@x 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{%
  \POE@comp@rectangle
  \psline(!\POE@dict{@@x -0.2 mul @@y neg})(!\POE@dict{@@x 0.2 mul @@y})
\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{%
  \POE@comp@rectangle
%    \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
    \POE@usefiberorwirestyle
    \psset{arrows=-, ArrowInside=-}%
    \psline(! \POE@dict{@@x} neg 0)(! \POE@dict{@@x} -0.6 mul @lw sub 0)%
    \psline(! \POE@dict{@@x} 0.6 mul 0)(! \POE@dict{@@x} 0)%
  \egroup
  \ifx\POE@key@switchstyle\POE@str@closed%
    \bgroup
      \POE@usefiberorwirestyle
      \psdot[dotsize=3\pslinewidth](! \POE@dict{@@x} 0.6 mul 0)%
      \psdot[dotsize=3\pslinewidth](! \POE@dict{@@x} -0.6 mul 0)%
      \psline[arrows=-, ArrowInside=-, linewidth=1.5\pslinewidth]%
        (! \POE@dict{@@x} -0.6 mul @lw)(! \POE@dict{@@x} 0.6 mul @lw)%      
    \egroup
  \else
    \psline[arrows=-, ArrowInside=-, linewidth=1.5\pslinewidth]%
      (! \POE@dict{@@x} -0.6 mul @lw add @lw 0.5 mul)%
      (! \POE@dict{@@x 0.45 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{%
  \POE@comp@rectangle
  \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}
% 
%    \begin{macrocode}
\newOptexpDipole{optarrowcomp}{}
\def\optarrowcomp@ref{%
  \POE@setref{%
    \ifx\POE@key@arrowcompshape\POE@str@rectangle
      /@@x \POE@key@arrowcompwidth\space 0.5 mul def
      /@@y \POE@key@arrowcompheight\space 0.5 mul def
    \else
      \POE@key@arrowcompwidth\space\POE@key@arrowcompheight\space
      min 0.5 mul dup /@@x ED /@@y ED
    \fi
    \POE@key@arrowcompangle\space dup 0 gt {
      { dup 180 ge { 180 sub } { exit } ifelse } loop
    } {
      { dup 0 lt { 180 add } { exit } ifelse } loop
    } ifelse dup /@arrowangle ED dup dup
    @@y @@x atan gt exch @@y @@x neg atan lt and {
      /@@dy @@y def
      tan @@y exch div /@@dx ED
    }{
      /@@dx @@x def
      tan @@x mul /@@dy ED
    } ifelse
  }%
}%
\def\optarrowcomp@comp{%
  \ifx\POE@key@arrowcompshape\POE@str@rectangle
    \POE@comp@rectangle
  \else
    \pscircle(!\POE@dict{@@x0 @@y0}){!\POE@dict{@@x}}
  \fi
  \begingroup
%    \end{macrocode}
% Set the style and execute the options directly, so we can use the correct 
% arrowscale and linewidth for the calculations.
%    \begin{macrocode}
    \psset{style=ArrowCompStyle}
    \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
      @arrowangle 2 copy cos mul 3 1 roll sin mul 
      \tx@UserCoor\space
    }%
    \ifx\POE@key@arrowcompshape\POE@str@rectangle
      \psline(!\POE@dict{@@dx -1.5 mul @@dy -1.5 mul})%
             (!\POE@dict{@@dx 1.3 mul @@dy 1.3 mul \@arrowshift VecAdd})
    \else
      \psline(!\POE@dict{@arrowangle dup cos @@x -1.5 mul mul exch sin @@x -1.5 mul mul})
             (!\POE@dict{@arrowangle dup cos @@x 1.3 mul mul exch sin @@x 1.3 mul mul \@arrowshift VecAdd})
    \fi
  \endgroup
\ignorespaces}%
%    \end{macrocode}
%
%    \begin{macrocode}
\newOptexpDipole{optbarcomp}{}
\def\optbarcomp@ref{%
  \POE@setref{%
    \ifx\POE@key@barcompshape\POE@str@rectangle
      /@@x \POE@key@barcompwidth\space 0.5 mul def
      /@@y \POE@key@barcompheight\space 0.5 mul def
    \else
      \POE@key@barcompwidth\space\POE@key@barcompheight\space
      min 0.5 mul dup /@@x ED /@@y ED
    \fi
    \POE@key@barcompangle\space dup 0 gt {
      { dup 180 ge { 180 sub } { exit } ifelse } loop
    } {
      { dup 0 lt { 180 add } { exit } ifelse } loop
    } ifelse dup /@barangle ED dup dup
    @@y @@x atan gt exch @@y @@x neg atan lt and {
      /@@dy @@y def
      tan @@y exch div /@@dx ED
    }{
      /@@dx @@x def
      tan @@x mul /@@dy ED
    } ifelse
  }%
}%
\def\optbarcomp@comp{%
  \ifx\POE@key@barcompshape\POE@str@rectangle
    \POE@comp@rectangle
    \psline[style=BarCompStyle](!\POE@dict{ @@dx neg @@dy neg })%
                               (!\POE@dict{@@dx @@dy})
  \else
    \pscircle(!\POE@dict{@@x0 @@y0}){!\POE@dict{@@x}}
    \psline[style=BarCompStyle]%
      (!\POE@dict{@barangle dup cos @@x neg mul exch sin @@x neg mul})
      (!\POE@dict{@barangle dup cos @@x mul exch sin @@x mul})
  \fi
\ignorespaces}%
%    \end{macrocode}
%
%
% \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
  }
}%
\let\fiberbox@comp\POE@comp@rectangle
%    \end{macrocode}
% \end{macro}
%
%
% \subsubsection{optcoupler}
% \begin{macro}{\optcoupler@nodes}
%    \begin{macrocode}
\def\optcoupler@nodes{%
  \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{%
    /@@x \POE@key@couplerwidth\space 0.5 mul def
    \ifx\POE@key@couplertype\POE@str@none
      \ifx\POE@key@couplersep\@empty
        /@@y \POE@key@couplerheight\space 0.5 mul 0.05 0.2 0.8 mul div mul def
      \else
        /@@y \POE@key@couplersep\space 0.5 mul def
      \fi
      /@@sep @@y def
    \else
      /@@y \POE@key@couplerheight\space 0.5 mul def
      \ifx\POE@key@couplersep\@empty
        \ifx\POE@key@couplertype\POE@str@ellipse
          /@@sep @@y 0.05 0.2 0.8 mul div mul def
        \else
          /@@sep @@y 0.5 mul def
        \fi
      \else
        /@@sep \POE@key@couplersep\space 0.5 mul def
      \fi
    \fi
    /@@y0 @@sep
    \ifx\POE@key@coupleralign\POE@str@bottom
    \else\ifx\POE@key@coupleralign\POE@str@top
      neg
    \else
      pop 0
    \fi\fi
    def
  }%
}%
%    \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@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@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@none
  \else\ifx\POE@key@couplertype\POE@str@ellipse
    \psellipse(! 0 \POE@dict{@@y0})(! \POE@dict{@@x @@y})
  \else
    \POE@comp@rectangle
    \ifx\POE@key@couplertype\POE@str@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@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{%
  \newOptexpFiberComp{%
%    \end{macrocode}
% A coupler may have only a single input node, which must then be duplicated
%    \begin{macrocode}
    /@@nodecount \the\POE@couplernodecount\space dup 1 le { pop 2 } if def
    @@y0 \POE@key@couplersep\space 0.5 mul add
    \POE@key@couplersep\space @@nodecount 1 sub div
    \ifx\POE@key@couplertype\POE@str@none
      \ifx\POE@key@coupleralign\POE@str@center
        pop pop @@y0 0
      \fi
    \fi
    1 1 @@nodecount
    {
      3 copy 1 sub mul sub exch pop [ @@x neg 3 -1 roll ] cvx 3 1 roll
    } for
    pop pop
    {@@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@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{\the\POE@couplernodecount}{})(\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{%
  \newOptexpFiberComp{%
    {@@x neg 0}
%    \end{macrocode}
% A coupler may have only a single output node, which must then be duplicated
%    \begin{macrocode}
    /@@nodecount \the\POE@couplernodecount\space dup 2 gt { 1 sub } if def
    @@y0 \POE@key@couplersep\space 0.5 mul add
    \POE@key@couplersep\space @@nodecount 1 sub div
    \ifx\POE@key@couplertype\POE@str@none
      \ifx\POE@key@coupleralign\POE@str@center
        pop pop @@y0 0
      \fi
    \fi
    1 1 @@nodecount
    {
      3 copy 1 sub mul sub exch pop [ @@x 3 -1 roll ] cvx 3 1 roll
    } for
    pop pop
  }%
  \pnode(0,0){\oenodeCenter{}}
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\wdmsplitter@comp}
%    \begin{macrocode}
\def\wdmsplitter@comp{%
  \ifx\POE@key@couplertype\POE@str@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{%
  \pspolygon(!\POE@dict{@@x neg \POE@clwh add @@y neg})%
            (!\POE@dict{@@x 0})%
            (!\POE@dict{@@x neg \POE@clwh add @@y})
}%
%    \end{macrocode}
% \end{macro}
%
% \subsection{Electrical components}
%
% \subsubsection{elecsynthesizer}
%
% \subsubsection{elecmixer}
%
% \begin{macro}{\elecmixer}
%    \begin{macrocode}
\def\elecmixer{\pst@object{elecmixer}}%
\def\elecmixer@i(#1)(#2)(#3){%
  \@ifnextchar\bgroup%
    {\elecmixer@ii(#1)(#2)(#3)}%
    {\elecmixer@ii(#1)(#2)(#3){}}%
}%
\def\elecmixer@ii(#1)(#2)(#3)#4{%
  \addafter@par{ref@angle=0}%
  \begin@OptexpObj
    \POE@calcCircRefNodes{#1}{#2}{#3}%
    \POE@drawcomponent{elecmixer}{#4}
    \ifPOE@backlayer
      \ifPOE@wirepresetin@top
        \drawwire@{WireIn}[stopnode=1](#1){}
      \else\ifPOE@fiberin@top
        \drawfiber@{FiberIn}[stopnode=1](#1){}
      \fi\fi
      \ifPOE@wirepresetout@top
        \drawwire@{WireOut1}[startnode=N]{}(#2)
      \else\ifPOE@fiberout@top
        \drawfiber@{FiberOut1}[startnode=N]{}(#2)
      \fi\fi
      \ifPOE@wirepresetout@bottom
        \drawwire@{WireOut2}[startnode=2, wirealign=center]{}(#3)
      \else\ifPOE@fiberout@bottom
        \drawfiber@{FiberOut2}[starnode=2, fiberalign=center]{}(#3)
      \fi\fi
    \fi
  \end@OptexpObj
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{elecmixer@ref}
%    \begin{macrocode}
\def\elecmixer@ref{%
  \POE@setref{\POE@key@elecmixersize\space 0.5 mul dup /@@x ED /@@y ED }%
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\elecmixer@nodes}
%    \begin{macrocode}
\def\elecmixer@nodes{%
  \newOptexpElecComp{{@@x neg 0} {0 @@y neg} {@@x 0}}%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\elecmixer@comp}
%    \begin{macrocode}
\def\elecmixer@comp{%
  \edef\@sz{\POE@key@elecmixersize\space 0.5 mul }%
  \pscircle(0,0){! \@sz}
  \psline(!\@sz 2 sqrt div neg dup)(!\@sz 2 sqrt div dup)
  \psline(!\@sz 2 sqrt div dup neg exch)(!\@sz 2 sqrt div dup neg)
}%
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{Electrical coupler}
%
% \begin{macro}{\eleccoupler}
%    \begin{macrocode}
\def\eleccoupler{\pst@object{eleccoupler}}%
\def\eleccoupler@i(#1)(#2){%
  \@ifnextchar(%)
    {\eleccoupler@ii(#1)(#2)}%
    {\eleccoupler@ii(#1)(#1)(#2)(#2)}%
}%
\def\eleccoupler@ii(#1)(#2)(#3)(#4){%
  \@ifnextchar\bgroup%
    {\eleccoupler@iii(#1)(#2)(#3)(#4)}%
    {\eleccoupler@iii(#1)(#2)(#3)(#4){}}%
}%
\def\eleccoupler@iii(#1)(#2)(#3)(#4)#5{%
  \begin@OptexpObj
    \ifPOE@backlayer
      \ifx\POE@key@eleccoupleralign\POE@str@top
        \pnode(#1){\oenodeRefA{}}
        \pnode(#3){\oenodeRefB{}}
      \else\ifx\POE@key@eleccoupleralign\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{eleccoupler}{#5}
    \ifPOE@backlayer
      \POE@Verb{%
        (1) (3) (\oenode{}{}) CorrectDipoleIfc 
        (2) (4) (\oenode{}{}) CorrectDipoleIfc 
      }%
      \ifPOE@wirepresetin@top
        \drawwire@{WireIn1}[stopnode=1](#1){}
      \else\ifPOE@fiberin@top
        \drawfiber@{FiberIn1}[stopnode=1](#1){}
      \fi\fi
      \ifPOE@wirepresetout@top
        \drawwire@{WireOut1}[startnode=3](#3){}
      \else\ifPOE@fiberout@top
        \drawfiber@{FiberOut1}[startnode=3](#3){}
      \fi\fi
      \ifx\POE@key@eleccouplertype\POE@str@directional
        \ifx\POE@key@eleccouplerinput\POE@str@left
          \ifPOE@wirepresetout@bottom
            \drawwire@{WireOut2}[startnode=N](#4){}
          \else\ifPOE@fiberout@bottom
            \drawfiber@{FiberOut2}[startnode=N](#4){}
          \fi\fi
        \else
          \ifPOE@wirepresetin@bottom
            \drawwire@{WireIn2}[stopnode=2](#2){}
          \else\ifPOE@fiberin@bottom
            \drawfiber@{FiberIn2}[stopnode=2](#2){}
          \fi\fi
        \fi
      \else
        \ifPOE@wirepresetout@bottom
          \drawwire@{WireOut2}[startnode=N](#4){}
        \else\ifPOE@fiberout@bottom
          \drawfiber@{FiberOut2}[startnode=N](#4){}
        \fi\fi
        \ifPOE@wirepresetin@bottom
          \drawwire@{WireIn2}[stopnode=2](#2){}
        \else\ifPOE@fiberin@bottom
          \drawfiber@{FiberIn2}[stopnode=2](#2){}
        \fi\fi
      \fi
    \fi
  \end@OptexpObj
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\eleccoupler@ref}
%    \begin{macrocode}
\def\eleccoupler@ref{%
  \POE@setref{%
    /@@x \POE@key@eleccouplerwidth\space 0.5 mul def
    /@@y \POE@key@eleccouplerheight\space 0.5 mul def
    \ifx\POE@key@eleccouplersep\@empty
      /@@sep @@y 0.75 mul def
    \else
      /@@sep \POE@key@eleccouplersep\space 0.5 mul def
    \fi
    /@@y0 @@sep
    \ifx\POE@key@eleccoupleralign\POE@str@bottom
    \else\ifx\POE@key@eleccoupleralign\POE@str@top
      neg
    \else
      pop 0
    \fi\fi
    def
  }%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\eleccoupler@nodes}
%    \begin{macrocode}
\def\eleccoupler@nodes{%
  \newOptexpElecComp{%
    {@@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}{\eleccoupler@comp}
%    \begin{macrocode}
\def\eleccoupler@comp{%
  \POE@comp@rectangle
  \psline(!\POE@dict{@@x -0.7 mul  @@y0 @@sep sub @@y 0.15 mul add})%
         (!\POE@dict{@@x 0.7 mul @@y0 @@sep add @@y 0.15 mul sub})%
  \psline(!\POE@dict{@@x 0.7 mul  @@y0 @@sep sub @@y 0.15 mul add})%
         (!\POE@dict{@@x -0.7 mul @@y0 @@sep add @@y 0.15 mul sub})%
  \psline[style=Wire, arrows=-, ArrowInside=-](\oenodeIfc{1}{})(\oenodeIfc{3}{})
  \ifx\POE@key@eleccouplertype\POE@str@directional
    \ifx\POE@key@eleccouplerinput\POE@str@left
      \psline[style=Wire, arrows=-, ArrowInside=-]([Xnodesep=-0.1]\oenodeIfc{2}{})(\oenodeIfc{N}{})
    \else
      \psline[style=Wire, arrows=-, ArrowInside=-](\oenodeIfc{2}{})([Xnodesep=0.1]\oenodeIfc{N}{})
    \fi
    \pscustom[style=OptComp]{%
      \moveto(!\POE@dict{@@x 0.15 add
               \ifx\POE@key@eleccouplerinput\POE@str@left neg \fi
               @@y0 @@sep sub 0.14 add})
      \rlineto(0,-0.04)
      \multido{\rx=0.12+-0.08}{4}{%
        \rlineto(0.05,-0.02)
        \rlineto(-0.1,-0.04)
        \rlineto(0.05,-0.02)
      }%
      \rlineto(0,-0.04)
    }%
  \else
    \psline[style=Wire, arrows=-, ArrowInside=-](\oenodeIfc{2}{})(\oenodeIfc{N}{})
  \fi
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\newOptexpElecDipole}
%    \begin{macrocode}
\def\newOptexpElecDipole{%
  \@ifnextchar[%]
    {\POE@newelecdipole}{\POE@newelecdipole[]}%
}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\POE@newfiberdipole}
%    \begin{macrocode}
\def\POE@newelecdipole[#1]#2{%
  \@ifnextchar\bgroup
    {\POE@newelecdipole@i[#1]{#2}}{\POE@newelecdipole@i[#1]{#2}{}}%
}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\POE@newelecdipole@i}
%    \begin{macrocode}
\def\POE@newelecdipole@i[#1]#2#3{%
  \@ifundefined{#2@i}{%
    \@namedef{#2}{\pst@object{#2}}%
    \expandafter\def\csname #2@i\endcsname(##1)(##2){%
      \@ifnextchar\bgroup%
        {\@nameuse{#2@ii}(##1)(##2)}%
        {\@nameuse{#2@ii}(##1)(##2){}}%
    }%
    \expandafter\def\csname #2@ii\endcsname(##1)(##2)##3{%
      \addbefore@par{#3}%
      \addafter@par{#1}%
      \begin@OptexpObj
        \ifPOE@backlayer
          \POE@regNodes{##1}{##2}
        \fi
        \POE@drawcomponent{#2}{##3}
        \ifPOE@backlayer
          \POE@Verb{ (1) (N) (\oenode{}{}) CorrectDipoleIfc }%
          \POE@PresetWireConn
        \fi
      \end@OptexpDipole
    }%
    \@ifundefined{#2@nodes}{\expandafter\def\csname #2@nodes\endcsname{\POE@elecdipole@nodes}}{}%
  }{%
    \PackageError{pst-optexp}{%
      elecdipole component '#2' already defined}%
  }%
\ignorespaces}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\elecsynthesizer@ref}
%    \begin{macrocode}
\newOptexpElecDipole{elecsynthesizer}{position=start, innercompalign=absolute}
\def\elecsynthesizer@ref{%
  \POE@setref{%
    \POE@key@synthwidth\space 0.5 mul
    \POE@key@synthheight\space 0.5 mul
    2 copy min /@@sz ED
    \ifx\POE@key@synthshape\POE@str@circle
      pop pop @@sz dup
    \fi
    /@@y ED /@@x ED
  }%
}%
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\elecsynthesizer@comp}
%    \begin{macrocode}
\def\elecsynthesizer@comp{%
  \ifx\POE@key@synthshape\POE@str@circle
    \pscircle(!\POE@dict{@@x0 @@y0}){!\POE@dict{@@x}}
  \else
    \POE@comp@rectangle
  \fi
  \psrotate(\oenodeCenter{}){!\POE@dict{@@ang}}{%
  \psset{style=SynthStyle}%
  \begingroup
%    \end{macrocode}
% Negative units are not possible with parametric or function plots.
%    \begin{macrocode}
    \let\POE@tempA\@empty
    \let\POE@tempB\@empty
    \ifdim\psxunit<0pt 
      \psset{xunit=-\psxunit}
      \def\POE@tempA{-1 mul\space}%
    \fi
    \ifdim\psyunit<0pt 
      \psset{yunit=-\psyunit}
      \def\POE@tempB{-1 mul\space}%
    \fi
    \ifx\POE@key@synthtype\POE@str@sine
      \parametricplot[plotpoints=100]{-1}{1}{%
        \POE@dict{@@sz 0.7 mul t mul t 180 mul \POE@tempA sin @@y -0.35 mul mul \POE@tempB }}%
    \else\ifx\POE@key@synthtype\POE@str@pulse
      \psplot[plotpoints=100]{-0.25}{0.25}{2.7182818 x 0.04 div dup mul neg exp 0.3 mul 0.13 sub \POE@tempB}%
    \fi\fi
  \endgroup
  \ifx\POE@key@synthtype\POE@str@rectangle
    \psline(!\POE@dict{@@sz -0.7 mul @@sz -0.35 mul})%
           (!\POE@dict{@@sz 0.7 mul -1 1 \POE@key@synthrectwidth\space sub 2 mul add mul @@sz -0.35 mul})%
           (!\POE@dict{@@sz 0.7 mul -1 1 \POE@key@synthrectwidth\space sub 2 mul add mul @@sz 0.35 mul})%
           (!\POE@dict{@@sz 0.7 mul @@sz 0.35 mul})%
           (!\POE@dict{@@sz 0.7 mul @@sz -0.35 mul})
  \else\ifx\POE@key@synthtype\POE@str@sawtooth
    \psline(!\POE@dict{@@sz -0.6 mul @@sz -0.4 mul})%
           (!\POE@dict{@@sz 0.6 mul @@sz 0.4 mul})%
           (!\POE@dict{@@sz 0.6 mul @@sz -0.4 mul})
  \else\ifx\POE@key@synthtype\POE@str@triangle
    \psline(!\POE@dict{@@sz -0.6 mul @@sz -0.4 mul})%
           (!\POE@dict{0 @@sz 0.4 mul})%
           (!\POE@dict{@@sz 0.6 mul @@sz -0.4 mul})
  \else
    \@ifundefined{elecsynthesizer@custom}{}{\elecsynthesizer@custom}%
  \fi\fi\fi}%
}%
%    \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 (\n) strcat print
} bind def
/CompUnknownWarning {
  (Component ') exch strcat (' unknown) strcat Warning
} bind def
/OneFiberCompWarning {
  (Found only one unsupported component in beam path, drawing no beam) Warning
} bind def
/FiberCompWarning {
  (Found an unsupported component in beam path, stopping beam path) Warning
} 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}{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}.
% \begin{pssyntax}
%   \PSvar{XA} \PSvar{YA} \PSvar{XB} \PSvar{YB} \PSvar{XG} \PSvar{YG} \PSop{calcNodes}
% \end{pssyntax}
%    \begin{macrocode}
/calcNodes {
  (calcNode) DebugBegin
  /YG exch def /XG exch def
  /by exch YG sub def
  /bx exch XG sub def
  /ay YG 3 -1 roll sub def
  /ax XG 3 -1 roll sub def
  ax ay NormalizeVec bx by NormalizeVec VecAdd
  2 copy Pyth abs 1e-4 lt { 
    pop pop ax ay -90 matrix rotate dtransform
  } if
  /cy ED /cx ED
  /c ax bx add ay by add Pyth 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
  } if
  cx cy NormalizeVec 2 copy
  XG YG VecAdd /Y@A ED /X@A ED
  XG YG 4 2 roll VecSub /Y@B ED /X@B ED
%    \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}
  true
  ax by mul ay bx mul sub 0 le {
    pop false
    Y@A X@A 
    /X@A X@B def
    /Y@A Y@B def
    /X@B exch def
    /Y@B 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
  { inttostr
    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}{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}{PathIfc}
% Define an interface which is given by an arbitrary path.
%   \begin{pssyntax}
%     \PSproc{X Y} \PSarray{path} \PSproc{scl} \PSvar{NAlow NAup} \PSop{PathIfc}
%   \end{pssyntax}
%    \begin{macrocode}
/PathIfc {
  pop pop /NAup 0 def /NAlow 0 def 
%    \end{macrocode}
% This kind of interface doesn't allow to switch off the NA-settings,
% because the interface is defined only inside the NA.
%    \begin{macrocode}
  3 1 roll /Path ED
  exec 3 -1 roll exec /Y ED /X 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}, \PSproc{CurvedIfc} or \PSproc{PathIfc}.
% \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.
%
% These are used for checks of the \opt{beamalign} and \opt{fiberalign} parameters.
%    \begin{macrocode}
/relative 0 def /absolute 1 def /center 2 def /firstcomp 3 def
%    \end{macrocode}
% 
% These constants are used to describe the characteristics of interfaces.
%    \begin{macrocode}
/refl 0 def /trans 1 def /absorb 2 def /refltrans 3 def /auto 4 def /undefined -1 def
%    \end{macrocode}
% 
% These give the ordering of the internal interfaces of a component.
%    \begin{macrocode}
/desc 0 def /asc 1 def /amb 2 def
%    \end{macrocode}
% 
% The possible status after computing the outgoing vector at an interface.
%    \begin{macrocode}
/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, 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
  13 dict dup 3 1 roll def begin
  /name ED
  /forcebeaminside ED
  /allowbeaminside ED
  /ambiguous ED
  /grating false def
  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) (2) IfcCopy
      (2) (N) IfcAlias
  }{
    N -1 1 { %
      inttostr exch name 3 1 roll {sc} NewCompIfc
    } for
    N inttostr (N) IfcAlias
  } ifelse
  ambiguous ambIfc 0 gt and { 
    ambIfc inttostr (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) (2) IfcCopy
    (2) (N) IfcAlias
  }{
    N -1 1 {
      inttostr
      {0 1} 0 0 absorb name 6 -1 roll {PlainIfc} {sc} NewCompIfc
    } for
    N inttostr (N) IfcAlias
  } ifelse
  end
  pop
  DebugEnd
} 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}{IfcAlias}
%   Create an alias of an interface. This involves creating also an
%   alias for the associated node.  Must be called withing
%   \PSvar{NewOptexpComp}.
%
%   \begin{pssyntax}
%     \PSstring{OrigPN} \PSstring{AliasPN} \PSop{IfcAlias}
%   \end{pssyntax}
%    \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}{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 number or name. 
%   \begin{pssyntax}
%     \PSstring{NameStem} \PSstring{IDStem} \PSop{CompAlias}
%   \end{pssyntax}
%    \begin{macrocode}
/CompAlias {
%    \end{macrocode}
% Copy the component dictionary
%    \begin{macrocode}
  2 copy cvn dup currentdict exch known { 
    load def 
  } { 
    pop 
  } ifelse
  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}
  mark (A) (B) (@A) (@B) (Center) (Label) (Rotref) 
       (TrefA) (TrefB) (@TrefA) (@TrefB) (Ext) (Origin)
  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 
%    \end{macrocode}
% Copy additional external nodes, the maximum is 8 (all combinations of
% l, r, t, b, c). Old and new node name stems are still on the stack.
%    \begin{macrocode}
  exch 1 1 8 {
    3 copy
    (Ext) exch 5 string cvs strcat dup 3 1 roll 
    NodeName 3 1 roll NodeName
    dup currentdict exch known {
      load def pop
    } {
      pop pop pop exit
    } ifelse
  } for
  pop pop
  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}{GetIfcCenterCorr}
%   Get the coordinates of an interface node. This checks if corrected
%   coordinates for proper connection handling are available.
%   \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 ambiguous, 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}
      beamdiffractionorder null eq not name cvn load /grating get and {
%    \end{macrocode}
% A grating (AOM) and a beamdiffractionorder was selected. In that case,
% \opt{beammode} has no effect, and for beamdiffractionorder=0 the
% interface is transmittive, otherwise refl or refltrans
%    \begin{macrocode}
        beamdiffractionorder dup 0 eq { pop () } if
        (C) exch 20 string cvs strcat 
        dup (P@) exch strcat cvn name cvn load exch known not {
%    \end{macrocode}
% The choosen beamdiffractionorder is not defined, select the closest one and issue a warning
%    \begin{macrocode}
          pop beamdiffractionorder dup sign neg 1 {
            (C) exch 5 string cvs dup 3 1 roll strcat 
            dup (P@) exch strcat cvn name cvn load exch known {
              3 -1 roll pop
              (Diffraction order ) beamdiffractionorder 5 string cvs strcat
              ( is not defined, using ) 4 -1 roll strcat strcat Warning
              exit
            } {
              pop
            } ifelse
          } for
        } if
        /@@centerifc ED
        mark @@centerifc name name GetRefIndex
        beamdiffractionorder 0 eq { 
          trans 
        }{ 
          name @@centerifc GetIfcMode refltrans eq {
            refltrans
          }{
            refl
          } ifelse
        } ifelse
      }{ 
        /@@centerifc (C) def
        [ @@centerifc name
        name GetRefIndex
        beammode auto eq {
          CurrVecTmp @@centerifc name GetPlaneVec 
          name @@centerifc GetIfcMode refltrans eq { -90 matrix rotate dtransform } if
          NormalVec outToPlane GetIfcCenter @@centerifc name GetIfcCenter @ABVect DotProd
          0 lt { 
            trans 
          }{ 
            name @@centerifc GetIfcMode 
            refltrans eq { 
              refltrans 
            }{ 
              refl 
            } ifelse 
          } ifelse
        } {
          beammode dup refl eq { 
%    \end{macrocode}
% in case, the ambiguous interface is refltrans
%    \begin{macrocode}
            pop name @@centerifc GetIfcMode dup refltrans eq not { pop refl } if
          } if
        } ifelse
      } 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 
      @@centerifc 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
      centerDist -1 eq { pop dup 0 gt } if
      { /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
    beampathcount 0 eq {
      cleartomark mark exit
    } if
%    \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
%    \end{macrocode}
% Adjust the alignment of a node interface, if it is to be aligned
% perpendicular to the beam vector (beamnodealign=vector).
%    \begin{macrocode}
    CompName cvn load begin 
      currentdict /adjustRel known aligntovector and {
        IfcNum IfcName load begin
          currentdict /RX known not {
%    \end{macrocode}
% Only exchange the coordinates of the beam vector, the sign is not
% important for the interface vector.
%    \begin{macrocode}
            2 copy neg exch CM dtransform CompMtrx idtransform
            /DY ED /DX ED
          } if
        end
      } if
    end
    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
      beampathcount 1 add PN eq {
        IfcCnt PN sub {pop} repeat
        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}{TraceInterfacePath}
%    \begin{macrocode}
/TraceInterfacePath {
  tx@IntersectDict begin
    /ArrowA { {currentpoint} stopped {moveto}{pop pop pop pop} ifelse } def
    {} TraceCurveOrPath 
    currentdict /ArrowA undef
  end
} 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
  /CurrPath false def
  /CurrUpT false def
  /CurrLowT false def
  /ret missed def
  /PN 1 def
  {
    PN IfcCnt gt {
      exit
    } if
    beampathcount 0 eq {
      cleartomark mark 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}
% Adjust the alignment of a node interface, if it is to be aligned
% perpendicular to the beam vector (beamnodealign=vector). The alignment
% is carried out with the median vector of upper and lower beam.
%    \begin{macrocode}
    CompName cvn load /adjustRel known aligntovector and {
      connectifc PrevCorrect PN 2 gt and PN 2 eq or and {
        CurrVecUp CurrVecUp CurrPCenter PrevPCenter PrevMode 
        currentdict /relAngleUp known { relAngleUp } { 0 } ifelse 
        connectInterfaces pop
        CurrVecLow CurrVecLow CurrPCenter PrevPCenter PrevMode 
        currentdict /relAngleLow known { relAngleLow } { 0 } ifelse 
        connectInterfaces pop
      } {
        CurrVecUp CurrVecLow
      } ifelse
      VecAdd NormalizeVec
      CompName cvn load begin
        IfcNum IfcName load begin
          currentdict /RX known not {
            CM dtransform CompMtrx idtransform
            /DX ED neg /DY ED
          } {
            pop pop
          } ifelse
        end
      end
    } if
%    \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
    /PrevUp /CurrUp load def
    /PrevUpT /CurrUpT load def
    /PrevPath /CurrPath load def
    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
    currentdict /isectT known currentdict /isectPath known and { 
      /CurrUpT isectT def 
      /CurrPath isectPath def
    } if
    /n1 oldn1 def
%    \end{macrocode}
% Calculate new lower vector and intersection point
%    \begin{macrocode}
    /PrevLow /CurrLow load def
    /PrevLowT /CurrLowT load def
    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}
    currentdict /isectT known {
      /CurrLowT isectT def
    } if
    /PrevR CurrR def
    PrevR type /realtype eq {
      /CurrCenter load /PrevCenter ED
    } if
    IfcNum CompName isCurvedIfc {
      IfcNum CompName LoadIfc
      tx@Dict begin Pyth end /CurrR ED
      ToVec /CurrCenter ED
    } {
      /CurrR false def
      /CurrCenter false def
    } ifelse
    IfcNum CompName isPathIfc not {
      /CurrPath false def
      /CurrLowT false def
      /CurrUpT false def
    } if
    PN 1 gt currentdict /fillBeam known and {
      draw {
        /DrawnSegm DrawnSegm 1 add def
        PrevUp moveto CurrUp lineto
        IfcNum CompName isCurvedIfc {
          CurrCenter CurrUp CurrLow 
          4 copy 3 -1 roll eq 3 1 roll eq and {
            6 {pop} repeat
          } {
            TangentCrosspoint
            CurrLow CurrR arct
          } ifelse
        } {
          IfcNum CompName isPathIfc {
            CurrPath CurrUpT CurrLowT TraceInterfacePath
          } {
            CurrLow lineto
          } ifelse
        } ifelse
        PrevLow lineto
        PrevPath type /booleantype eq not {
          PrevPath PrevLowT PrevUpT TraceInterfacePath
        } {
          PrevR type /booleantype eq not {
            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
        } 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 
    beampathcount 1 add PN eq or {
      DrawnSegm 0 gt currentdict /fillBeam known and { 
        fillBeam newpath 
        /DrawnSegm 0 def
      } if
      IfcCnt PN sub {pop} repeat
      ret tir eq {
        (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 {
%    \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
    /lastVecTmpUp load /lastVecTmpLow load
    /prevVecLow ED /prevVecUp ED
  } if
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{DrawbeamPrepare}
%   Prepare the data points for drawing with \PSop{DrawbeamSimple} and
%   \PSop{DrawbeamArrowInside}.
%    \begin{macrocode}
/DrawbeamPrepare {
%    \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
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{DrawbeamSimple}
%    \begin{macrocode}
/DrawbeamSimple {
  pop 5 copy 3 -1 roll pop 
  ArrowA pop pop pop pop
  counttomark 3 idiv -1 2 {
    pop {
      lineto
    }{
      moveto
    } ifelse
  } for
  {CP 4 2 roll ArrowB lineto pop pop } {moveto} ifelse
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{DrawbeamArrowInside}
% 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}
/DrawbeamArrowInside {
  6 copy pop
  /y1 ED /x1 ED pop /y2 ED /x2 ED
  /Alpha y2 y1 sub x2 x1 sub Atan def
  pop 3 -1 roll 5 1 roll 
  ArrowA 
%    \end{macrocode}
% dx add, and dy add, to get the current point at the end of the arrow tip.
%    \begin{macrocode}
  x1 Alpha cos arrowlength mul add
  y1 Alpha sin arrowlength mul add
  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
    arrowminlength ge 
    exch arrowmaxlength dup 0 lt 
    3 1 roll le or and {
      x1 y1
      arrowpos 1 gt {
        /Alpha y2 y1 sub x2 x1 sub Atan def
        /dArrowPos dArrowPosStart abs def
        /ArrowPos ArrowPosStart def
        arrowno {
          /ArrowPos ArrowPos dArrowPos add def
          x1 Alpha cos ArrowPos mul add
          y1 Alpha sin ArrowPos mul add
          6 index { ArrowInside } if
          pop pop
        } repeat
      }{
        arrowno 1 gt { 
          1.0 arrowno 1.0 add div
        }{
          dArrowPosStart
        } ifelse /dArrowPos ED
        /ArrowPos ArrowPosStart def
        arrowno {
          /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
  {CP 4 2 roll ArrowB lineto pop pop } {moveto} ifelse
} 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}{isCurvedIfc}
%  Check if interface \PSvar{IfcNum} of componente \PSvar{compname} is curved.
%   \begin{pssyntax}
%     \PSvar{IfcNum} \PSstring{compname} \PSop{isCurvedIfc} \PSvar{bool}
%   \end{pssyntax}
%    \begin{macrocode}
/isCurvedIfc {
  cvn load begin
    IfcName load /RX known
  end
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{isPathIfc}
%  Check if interface \PSvar{IfcNum} of componente \PSvar{compname} is an arbitrary path.
%   \begin{pssyntax}
%     \PSvar{IfcNum} \PSstring{compname} \PSop{isPathIfc} \PSvar{bool}
%   \end{pssyntax}
%    \begin{macrocode}
/isPathIfc {
  cvn load begin
    IfcName load /Path 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
  currentdict /isectT undef currentdict /isectPath undef
  2 copy 2 copy LoadIfc % IfcNum name IfcNum name path
  dup type /arraytype eq { % is an path interface
    dup /isectPath exch def
    3 1 roll pop pop PathInterface % IfcNum name t X0' Y0' Xout Yout status
    dup missed eq not { 6 -1 roll /isectT exch def } if
  } {
    6 -2 roll 
    isCurvedIfc { CurvedInterface }{ PlainInterface } ifelse
  } 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 isCurvedIfc {
        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
      currentdict /Path known {
        Path TransformPath
      } {
        X Y
        CompMtrx transform CM itransform
        currentdict /RX known { RX RY }{ DX DY } ifelse
        CompMtrx dtransform CM idtransform
      } ifelse
    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}. This is only done for ``node interfaces'', which
%   are created automatically when drawing beams through nodes.
%   \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 aligntovector not and {
    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 {
%    \end{macrocode}
% first comp and we do not start inside
%    \begin{macrocode}
            5 -2 roll
            pop pop
            2 copy 5 2 roll
          } {
            startinsidecount 0 gt N startinsidecount sub 1 gt and {
%    \end{macrocode}
% we do not use all segments of the first component
%    \begin{macrocode}
              3 -1 roll dup 4 1 roll
              N 1 sub startinsidecount sub mul
              6 -2 roll pop add dup 5 2 roll
            } if
          } ifelse
        } if
        last stopinsidecount 0 gt N stopinsidecount sub 1 gt and and {
          % 1 1 1 N N
          3 -1 roll dup 4 1 roll stopinsidecount mul
          6 -1 roll dup 7 1 roll add 3 1 roll pop pop dup
        } 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 inttostr 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}.
% \begin{pssyntax}
% \PSvar{num} \PSop{IfcName} \PSname{P@num}
% \end{pssyntax}
%    \begin{macrocode}
/IfcName {
  inttostr (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 node name from a string or number.
% \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}{VecSub}
% Subtraction of two vectors.
% \begin{pssyntax}
%   \PSvar{Xa Ya Xb Yb} \PSop{VecSub} \PSvar{Xa-Xb Ya-Yb}
% \end{pssyntax}
%    \begin{macrocode}
/VecSub {
    neg 3 -1 roll add 3 1 roll neg 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 {
    ToPnt cvx
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{ToPnt}
%   Convert two numbers to an array holding the two values.
%   \begin{pssyntax}
%     \PSvar{X Y} \PSop{ToPnt} \PSarray{X Y}
%   \end{pssyntax}
%    \begin{macrocode}
/ToPnt {
    [ 3 1 roll ]
} 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}
% Vector from (Xb,Yb) to (Xa,Ya)
% \begin{pssyntax}
%   \PSvar{Xa Ya Xb Yb} \PSop{@ABVect} \PSvar{(Ya - Yb) (Xa - Xb)}
% \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{NormalVec}, 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 have been
%   constructed with \PSvar{NormalVec}.
%   \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
/ReflectGratVec {
  (ReflectGratVec) 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
    mode refltrans eq {
      neg exch NormalVec ReflectVec ok
    } {
      NormalVec
      mode trans eq {
        n1 n2 RefractVec
        2 copy 0 eq exch 0 eq and { tir } { ok } ifelse
      } {
        ReflectVec ok
      } ifelse 
    } 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}{PathInterface}
%   \begin{pssyntax}
%     \PSarray{path} \PSop{PathInterface} \PSvar{X0' Y0' Xout Yout status}
%   \end{pssyntax}
%    \begin{macrocode}
/PathInterface {
  (PathInterface) DebugBegin
  [ [X0 Y0] [X0 Xin add Y0 Yin add] ] exch 
  tx@IntersectDict begin IntersectLinePath end % [pathseg] t [isect]
  dup length 0 eq {
    pop pop pop 0 0 missed
  } {
    aload pop
    Xin Yin Xin Yin 
    8 -2 roll exch % I.x I.y Xin Yin Xin Yin t [pathseg]
    exch dup 9 1 roll exch % t I.x I.y Xin Yin Xin Yin t [pathseg]
    dup length 2 eq { % a line
      exch pop
      aload pop aload pop 3 -1 roll aload pop VecSub % t I.x I.y Xin Yin Xin Yin dXp dYp
    } {
      exch dup cvi sub DeriveCurve
    } ifelse
    % the following part is copied from /PlainInterface
    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
    % t X0' Y0' Xout Yout status 
  } 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}{RelConnAngle}
% Calculate start angle of \cs{nccurve} from CompA to CompB
%
% \begin{pssyntax}
%   \PSvar{Xb Yb Xa Ya A B} \PSvar{fiberalign} \PSop{RelConnAngle} \PSvar{angle}
% \end{pssyntax}
%    \begin{macrocode}
/RelConnAngle {
  (RelConnAngle) 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 {
        RelConnAngle@center
      }{
        3 1 roll pop pop
        RelConnAngle@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 {
      RelConnAngle@center
    }{
      3 1 roll pop pop
      RelConnAngle@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}{/RelConnAngle@ref}
% Calculate the vector of the reference line of \PSvar{CompA}.
% \begin{pssyntax}
%   \PSstring{CompA} \PSop{RelConnAngle@ref} \PSvar{dX dY}
% \end{pssyntax}
%    \begin{macrocode}
/RelConnAngle@ref {
  dup (A) NodeName exch (B) NodeName
  @GetCenter 3 -1 roll @GetCenter @ABVect 
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{/RelConnAngle@tref}
% Same as \PSname{RelConnAngle@ref} but uses the transformed reference nodes.
% \begin{pssyntax}
%   \PSvar{CompA} \PSop{RelConnAngle@ref} \PSvar{dX dY}
% \end{pssyntax}
%    \begin{macrocode}
/RelConnAngle@tref {
  dup (TrefA) NodeName exch (TrefB) NodeName
  @GetCenter 3 -1 roll @GetCenter @ABVect 
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{/RelConnAngle@center}
%   Calculate the vector from the center node of \PSvar{CompA} to the
%   node \PSstring{Xa, Ya}.
% \begin{pssyntax}
%   \PSvar{Xa Ya CompA} \PSop{RelConnAngle@center} \PSvar{dX dY}
% \end{pssyntax}
%    \begin{macrocode}
/RelConnAngle@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 {
  (GetIfcOrNodeCoord) DebugBegin
  dup xcheck {
    exch pop exec
  } {
    nametostr exch nametostr exch GetIfcCenter
  } ifelse
  DebugEnd
} 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 dictionary 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}{ClipFadeValue}
% Clip a number to the range [0:1].
%   \begin{pssyntax}
%     \PSvar{value} \PSop{ClipFadeValue} \PSvar{clippedvalue}
%   \end{pssyntax}
%    \begin{macrocode}
/ClipFadeValue {
  dup 0 lt { pop 0 }{ dup 1 gt { pop 1 } if } ifelse
} bind def
%    \end{macrocode}
% \end{macro}
% \begin{macro}{fadeto@}
% The different fadeto modes.
%    \begin{macrocode}
/fadeto@white {
  FadeFunc ClipFadeValue @S mul @H exch @B sethsbcolor
} bind def
/fadeto@black {
  FadeFunc ClipFadeValue @B mul @H exch @S exch sethsbcolor
} bind def
/fadeto@transparency {
  FadeFunc ClipFadeValue @T mul .setopacityalpha
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{fadefunc@}
%   The default fade functions, which are selected with the parameter
%   'fadefuncname'. The clipping is done afterwards.
%    \begin{macrocode}
/fadefunc@linear {
  neg 1 add
} bind def
/fadefunc@squared {
  dup mul neg 1 add
} bind def
/fadefunc@gauss {
  0.4 div dup mul neg Euler exch exp
} bind def
/fadefunc@exp {
  -6 mul Euler exch exp
} bind def
%    \end{macrocode}
% \end{macro}
% \begin{macro}{FadeStroke}
% Implement the 'fade' linestyle.
%    \begin{macrocode}
/FadeStroke {
  /FadeFunc ED /FadeToColor ED /@T ED
  PathLength dup /@L ED exch div /@dl ED
  mark
  { false counttomark 3 roll }
  { true counttomark 3 roll }
  {} {} pathforall
  currenthsbcolor /@B ED /@S ED /@H ED
  newpath /currL 0 def
  counttomark 3 idiv 1 1 3 -1 roll {
    pop
    { % lineto 
      /y2 ED /x2 ED  x2 x1 sub y2 y1 sub 2 copy 
      dup mul exch dup mul add sqrt dup  @L div exch
      @dl div 1 add floor dup dup
      4 2 roll div 5 1 roll
      1 1 3 -1 roll {
        5 copy 4 copy 2 copy eq not { fadecorrect add } if exch div VecScale
        6 2 roll 1 sub dup 0 eq not { fadecorrect sub } if exch div VecScale
        x1 y1 VecAdd moveto x1 y1 VecAdd lineto
        mul currL add FadeToColor
        stroke
      } for
      4 1 roll pop pop mul currL add /currL ED
      /y1 y2 def /x1 x2 def
    } { % moveto 
      /y1 ED /x1 ED
    } ifelse
  } for
  pop
} def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{TransformPath}
%   Transforms a path (as defined by \cs{pssavepath} from
%   \nxLPack{pst-intersect}) using the \opt{currentmatrix} and the
%   \opt{CompMtrx} of the component. That is used only by \opt{LoadIfc}.
%   \begin{pssyntax}
%     \PSarray{path} \PSop{TransformPath} \PSarray{path'}
%   \end{pssyntax}
%    \begin{macrocode}
/TransformPath {
  mark [ 3 -1 roll aload pop 
  counttomark 1 add counttomark 1 add exch 1 roll
  {
    counttomark 1 eq { cleartomark exit } if
    dup /curvetype eq {
      7 1 roll
      3 { CompMtrx transform CM itransform 7 2 roll } repeat
      counttomark -1 roll dup counttomark 1 roll
      7 roll
    } {
      3 1 roll CompMtrx transform CM itransform 3 -1 roll
      counttomark -1 roll dup counttomark 1 roll
      3 roll
    } ifelse
  } loop
  ]
} bind def
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{DeriveCurve}
%   Calculate the derivative of a curve at its parameter \PSvar{t}. This
%   works only for the special case of third-order Bezier curves.
%
%   \begin{align*}
%     B(t)  & = (1-t)^3 P_0 + 3(1-t)^2 t P_1 + 3(1-t)t^2 P_2 + t^3 P_3\\
%     B'(t) & = -3(1-t)^2 P_0 + 3(3t^2–4t+1) P_1 + 3(2t–3t^2) P_2 + 3t^2 P_3
%   \end{align*}
%   \begin{pssyntax}
%     \PSarray{curve} \PSvar{t} \PSop{DeriveCurve} \PSvar{dX dY}
%   \end{pssyntax}
%    \begin{macrocode}
/DeriveCurve {
  (DeriveCurve) DebugBegin
  exch dup length 4 eq not {
    pop pop 0 0
  } {
    aload pop 5 -1 roll
    dup 1 exch sub dup mul -3 mul exch % P0 P1 P2 P3 C0=(-3(1-t)^2) t
    dup dup -4 mul 1 add exch dup mul 3 mul add 3 mul exch % P0 P1 P2 P3 C0 C1=(3(3t^2-4t+1)) t
    dup dup 2 mul exch dup mul -3 mul add 3 mul exch % P0 P1 P2 P3 C0 C1 C2=(3(2t-3t^2)) t
    dup mul 3 mul % P0 P1 P2 P3 C0 C1 C2 C3=3t^2
    8 copy
    0 6 -1 3 { -1 roll 0 get 3 -1 roll mul add } for
    9 1 roll
    0 6 -1 3 { -1 roll 1 get 3 -1 roll mul add } for
  } ifelse
  DebugEnd
} bind def
%    \end{macrocode}
% \end{macro}
% 
% \begin{macro}{GetBezierDeriv}
%   Calculate the derivative of the bezier curve at the coordinate
%   \PSvar{t}.
%   \begin{equation}
%     C(t) = \sum_{i=0}^n B_{i,n}(t)P_i\quad\text{with}\quad B_{i,n}(t) = (n over i) t^i(1-t)^{n-i}
%   \end{equation}
%   \begin{equation}
%     C'(t) = \sum_{i=0}^n B'_{i,n}(t)P_i\quad\text{with}\quad B'_{i,n}(t) = (n over i)(i t^{i-1}(1-t)^{n-i} - (n-i)t^i(1-t)^{n-i-1})
%   \end{equation}
%   \begin{pssyntax}
%     \PSarray{[P0]\ldots[P\_n]} \PSvar{t} \PSop{DeriveBezier} \PSvar{x y}
%   \end{pssyntax}
%    \begin{macrocode}
/GetBezierDeriv { 				% t on stack
  10 dict begin					% hold all local
  /t ED
  /t1 1 t sub def				% t1=1-t
  dup length /BezierOrder exch def
  /Points exch def
  /Coeff tx@FuncDict begin Pascal end BezierOrder get def		% get the coefficients
    0 0						% initial values for x y
    BezierOrder -1 0 {				% BezierOrder,...,2,1,0
      /I ED					% I=BezierOrder,...,2,1,0
      /J BezierOrder I sub def			% J=0,1,2,...,BezierOrder
      I 0 eq { 
        0 
      }{ 
        I t I 1 sub exp mul t1 J exp mul        %  i*t^{i-1}*(1-t)^{n-i} 
      } ifelse
      J 0 eq {
        0
      } {
        J t I exp mul t1 J 1 sub exp mul    % -(n-i)t^i(1-t)^{n-i-1}
      } ifelse
      sub Coeff J get mul
      Points I get aload pop 3 -1 roll VecScale VecAdd
    } for					% x y on stack
  end
} bind def
%    \end{macrocode}
% \end{macro}
%
% This fixes a problem in pst-intersect.pro v0.4
%    \begin{macrocode}
tx@IntersectDict begin 
/IntersectLinePath {
  3 dict begin
    PreparePath dup length /n exch def
    2 copy ElongateLine exch 3 -1 roll pop
    /isect [] def
    /t -1 def
    {
      /n n 1 sub def
      2 copy IntersectBeziers
      dup 5 1 roll LoadIntersectionPoints
      dup length 0 gt {
        /isect exch def
        0 get dup type /arraytype eq {
          aload pop add 0.5 mul 
        } if n add /t exch def
        exch pop
        exit
      } {
        pop pop pop
      } ifelse
    } forall
    t isect
  end
} bind def
end
%    \end{macrocode}
%
% \begin{macro}{GetCoordinatePair}
%   Get the coordinate pair at position \PSvar{n} (n goes from 1 to N) and remove the other coordinates
%   including mark from stack
%   \begin{pssyntax}
%     [ \PSvar{xN} \PSvar{yN} ... \PSvar{x1} \PSvar{y1} \PSvar{n} \PSop{GetCoordinatePair}
%   \end{pssyntax}
%    \begin{macrocode}
/GetCoordinatePair {%
  2 mul -2 roll counttomark 1 add 2 roll cleartomark
} bind def
%    \end{macrocode}
% \end{macro}
%    \begin{macrocode}
/GetFirstInputCoordinatePair { 1 GetCoordinatePair } bind def
%    \end{macrocode}
% If a coupler has only a single input node, this must be used for both nodes
%    \begin{macrocode}
/GetLastInputCoordinatePair { counttomark 2 idiv 1 sub GetCoordinatePair } bind def
%    \end{macrocode}
% \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>font-size
headings_flag       1
heading_prefix   "\\textbf{"
heading_suffix   "}\n"
quote		'"'
level		'!'
actual          '='
preamble
  "\\begin{theindex}\n"
item_1
  "\\par\\leavevmode\\hangindent10pt\\makebox[25pt][r]{ -- }"
item_01
  "\\par\\leavevmode\\hangindent10pt\\makebox[25pt][r]{ -- }"
item_x1
  "\\par\\leavevmode\\hangindent10pt\\makebox[25pt][r]{ -- }"
item_2
  "\\par\\leavevmode\\hangindent20pt\\makebox[50pt][r]{ -- -- }"
item_12
  "\\par\\leavevmode\\hangindent20pt\\makebox[50pt][r]{ -- -- }"
item_x2
  "\\par\\leavevmode\\hangindent20pt\\makebox[50pt][r]{ -- -- }"
%</indexstyle>
