%%
%% This is file `pst-optexp.tex',
%%
%% IMPORTANT NOTICE:
%%
%% Package `pst-optexp.tex'
%%
%% Christoph Bersch <usenet _at_ bersch.net>
%%
%% This program can be redistributed and/or modified under the terms
%% of the LaTeX Project Public License Distributed from CTAN archives
%% in directory CTAN:/macros/latex/base/lppl.txt.
%%
%% DESCRIPTION:
%%   `pst-optexp' is a PSTricks package to draw optical experimental setups
%%
%% HISTORY -> see file Changes
%%
%% Naming conventions:
%%   macros starting with 
%%      \POS are _P_STricks _O_ptexp _S_trings
%%      \POK are _P_STricks _O_ptexp _K_eys
%%      \ifPOE are _P_STricks _O_pt_e_xp ifs
%%
\csname PSToptexpLoaded\endcsname
\let\PSToptexpLoaded\endinput
%
%
\def\fileversion{2.1}
\def\filedate{2009/11/05}
\message{`pst-optexp' v\fileversion, \filedate\space (CB)}
%
\edef\PstAtCode{\the\catcode`\@} \catcode`\@=11\relax
\pst@addfams{optexp}
\pstheader{pst-optexp.pro}
\def\pst@optexpdict{tx@OptexpDict begin }
\SpecialCoor
%
%
% IF's
%
\newif\ifPOE@variable
\newif\ifPOE@crystal@voltage
\newif\ifPOE@crystal@caxisinv
\newif\ifPOE@reverse
\newif\ifPOE@crystal@lamp
\newif\ifPOE@component@optional
\newif\ifPOE@debug@showoptdots
\newif\ifPOE@endbox
\newif\ifPOE@thicklens
\newif\ifPOE@usefiberstyle
\newif\ifPOE@connjoin
\newif\ifPOE@fiber@
%
\newdimen\optboxwidth
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Strings
%
\def\POS@pol@polperp{perp}
\def\POS@pol@polparallel{parallel}
\def\POS@pol@polmisc{misc}
\def\POS@pol@polrcirc{rcirc}
\def\POS@pol@pollcirc{lcirc}
\def\POS@mirror@type@piezo{piezo}
\def\POS@mirror@type@plain{plain}
\def\POS@mirror@type@extended{extended}
\def\POS@optgrid@type@blazed{blazed}
\def\POS@optgrid@type@binary{binary}
%
\def\POS@lens@type@plainconvex{plainconvex}
\def\POS@lens@type@convexplain{convexplain}
\def\POS@lens@type@biconvex{biconvex}
\def\POS@lens@type@plainconcave{plainconcave}
\def\POS@lens@type@concaveplain{concaveplain}
\def\POS@lens@type@biconcave{biconcave}
%
\def\POS@labelref@relative{relative}
\def\POS@labelref@relgrav{relgrav}
\def\POS@labelref@global{global}
%
\edef\POS@filter@type@bandpass{bandpass}
\edef\POS@filter@type@bandstop{bandstop}
%
\edef\POS@coupler@type@none{none}
\edef\POS@coupler@type@elliptic{elliptic}
%
\edef\POS@optexp@top{top}
\edef\POS@optexp@bottom{bottom}
\edef\POS@optexp@center{center}
\edef\POS@optexp@closed{closed}
\edef\POS@optexp@opened{opened}
\edef\POS@optexp@basicname@default{tempNode@}
\edef\POS@optexp@basicname@postfix{Intern}
\edef\POS@optexp@extnode@postfix{ExtNode}
\edef\POS@detector@round{round}
\edef\POS@detector@diode{diode}
\edef\POS@bs@cube{cube}
\edef\POS@bs@plate{plate}
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% psstyles
%
\newpsstyle{OptionalStyle}{linestyle=dashed,dash=1.5pt 1pt}%
\newpsstyle{ExtendedMirror}{linestyle=none,%
                hatchwidth=0.5\POK@mirror@linewidth,
                hatchsep=1.4\POK@mirror@linewidth,%
                fillstyle=hlines}%
\newpsstyle{PiezoMirror}{fillstyle=solid,fillcolor=black!30}%
\newpsstyle{Beam}{linecolor=green!90!black,linewidth=\pslinewidth}%
\define@key[psset]{optexp}{newBeam}{\newpsstyle{Beam}{#1}}
\define@key[psset]{optexp}{addtoBeam}{\addtopsstyle{Beam}{#1}}
%
\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}}
%
\newpsstyle{OptComp}{}%
\define@key[psset]{optexp}{newOptComp}{\newpsstyle{OptComp}{#1}}
\define@key[psset]{optexp}{addtoOptComp}{\addtopsstyle{OptComp}{#1}}
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Parameterdefinitions
%
% General
\define@boolkey[psset]{optexp}[POE@component@]{optional}[true]{}
\define@key[psset]{optexp}{position}{\edef\POK@position{#1}}
\define@key[psset]{optexp}{abspos}{\edef\POK@abspos{#1}}
\define@key[psset]{optexp}{angle}{\edef\POK@angle{#1}}
\define@boolkey[psset]{optexp}[POE@]{usefiberstyle}[true]{}
%
% Label
\define@key[psset]{optexp}{labelangle}{\edef\POK@label@angle{#1}}
\define@key[psset]{optexp}{labeloffset}{\edef\POK@label@offset{#1}}
\define@key[psset]{optexp}{labelstyle}{\def\POK@label@style{#1}}
\define@key[psset]{optexp}{labelalign}{\def\POK@label@align{#1}}
\define@key[psset]{optexp}{labelref}{\edef\POK@label@ref{#1}}
\define@key[psset]{optexp}{label}{%
  \pst@expandafter\psset@@label{#1} {} {} {} {} {}\@nil
}%
% offset angle align ref
\def\psset@@label#1 #2 #3 #4 #5\@nil{%
  \edef\@empty@dot{.}%
  \edef\pst@temp{#4}%
  \ifx\pst@temp\@empty\else
     \ifx\pst@temp\@empty@dot\else
        \psset{labelref=#4}
     \fi
  \fi
  \edef\pst@temp{#3}
  \ifx\pst@temp\@empty\else
     \ifx\pst@temp\@empty@dot\else
        \psset{labelalign=#3}
     \fi
  \fi
  \edef\pst@temp{#2}%
  \ifx\pst@temp\@empty\else
     \ifx\pst@temp\@empty@dot\else
        \psset{labelangle=#2}%
     \fi
  \fi
  \edef\pst@temp{#1}%
  \ifx\pst@temp\@empty\else
     \ifx\pst@temp\@empty@dot\else
        \psset{labeloffset=#1}
     \fi
  \fi
}%
\define@boolkey[psset]{optexp}[POE@label@]{innerlabel}[true]{}
% for internal use only
\define@key[psset]{optexp}{ref@angle}{\edef\POK@label@refangle{#1}}
% labelrelative is obsolete
\define@choicekey[psset]{optexp}{labelrelative}[\val\nr]{true,false}[true]{%
  \ifcase\nr\relax
     \psset{labelref=relative}
  \or
     \psset{labelref=global}
  \fi
  \PackageWarning{pst-optexp}{labelrelative is obsolete, please use labelref=relative instead}
}
%
% Debug
\define@boolkey[psset]{optexp}[POE@debug@]{showoptdots}[true]{}
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Parameters for free-ray components
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Lens
\define@key[psset]{optexp}{lensheight}{\edef\POK@lens@height{#1}}
\define@key[psset]{optexp}{lenswidth}{\edef\POK@lens@width{#1}}
\define@key[psset]{optexp}{lensradiusleft}{\edef\POK@lens@radiusLeft{#1}}
\define@key[psset]{optexp}{lensradiusright}{\edef\POK@lens@radiusRight{#1}}
\define@boolkey[psset]{optexp}[POE@]{thicklens}[true]{}
\define@key[psset]{optexp}{lensradius}{%
   \psset{lensradiusleft=#1,%
      lensradiusright=#1}%
   \edef\POK@lens@radius{#1}%
}%
% Lens Type (only for backward compatibility)
% 0 -> plainconvex
% 1 -> convexplain
% 2 -> biconvex
% 3 -> plainconcave
% 4 -> concaveplain
% 5 -> biconcave
%
\define@key[psset]{optexp}{lenstype}{%
  \def\pst@tempA{#1}
  \edef\POK@lens@type{%
    \ifx\POS@lens@type@plainconvex\pst@tempA 0\else
    \ifx\POS@lens@type@convexplain\pst@tempA 1\else
    \ifx\POS@lens@type@biconvex\pst@tempA 2\else
    \ifx\POS@lens@type@plainconcave\pst@tempA 3\else
    \ifx\POS@lens@type@concaveplain\pst@tempA 4\else
    \ifx\POS@lens@type@biconcave\pst@tempA 5%
    \fi\fi\fi\fi\fi\fi%
}}
\define@key[psset]{optexp}{lens}{%
  \pst@expandafter\psset@@lens{#1} {} {} {} {} {}\@nil
}%
\def\psset@@lens#1 #2 #3 #4 #5\@nil{%
  \edef\pst@temp{#4}%
  \ifx\pst@temp\@empty\else
     \psset{lenswidth=#4}%
  \fi
  \edef\pst@temp{#3}%
  \ifx\pst@temp\@empty\else
     \psset{lensheight=#3}
  \fi
  \edef\pst@temp{#2}%
  \ifx\pst@temp\@empty
     \psset{lensradiusright=#1}%
  \else
     \psset{lensradiusright=#2}%
  \fi
  \psset{lensradiusleft=#1}%
}%
%
% Pinhole
\define@key[psset]{optexp}{innerheight}{\edef\POK@pinhole@iheight{#1}}
\define@key[psset]{optexp}{iwidth}{%
   \edef\POK@pinhole@iheight{#1}%
   \PackageWarning{pst-optexp}{iwidth is obsolete, use innerheight instead}
}
\define@key[psset]{optexp}{outerheight}{\edef\POK@pinhole@oheight{#1}}
\define@key[psset]{optexp}{owidth}{%
   \edef\POK@pinhole@oheight{#1}%
   \PackageWarning{pst-optexp}{owidth is obsolete, use outerheight instead}
}
\define@key[psset]{optexp}{phlinewidth}{\edef\POK@pinhole@linewidth{#1}}
%
% Beamsplitter
\define@key[psset]{optexp}{bssize}{\edef\POK@bssize{#1}}
\define@key[psset]{optexp}{bsstyle}{\edef\POK@bsstyle{#1}}
\define@key[psset]{optexp}{bswidth}{%
   \edef\POK@bssize{#1}%
   \PackageWarning{pst-optexp}{bswidth is obsolete, use bssize instead}%
}
%
% Crystal
\define@key[psset]{optexp}{crystalwidth}{\edef\POK@crystal@width{#1}}
\define@key[psset]{optexp}{crystalheight}{\edef\POK@crystal@height{#1}}
\define@key[psset]{optexp}{caxislength}{\edef\POK@crystal@caxislength{#1}}
\define@boolkey[psset]{optexp}[POE@crystal@]{voltage}[true]{}
\define@boolkey[psset]{optexp}[POE@crystal@]{caxisinv}[true]{}
\define@boolkey[psset]{optexp}[POE@crystal@]{lamp}[true]{}
\define@key[psset]{optexp}{lampscale}{\def\POK@lamp@scale{#1}}
%
% Mirror
\define@key[psset]{optexp}{mirrorwidth}{\edef\POK@mirror@width{#1}}
\define@key[psset]{optexp}{mirrorlinewidth}{\edef\POK@mirror@linewidth{#1}}
%\define@key[psset]{optexp}{mirrortype}{\edef\POK@mirror@type{#1}}% piezo, extended, plain
\define@choicekey+[psset]{optexp}{mirrortype}[\val\nr]{piezo,extended,plain}%
   {\edef\POK@mirror@type{#1}}%
   {\PackageError{pst-optexp}{Unknown value '\val' for mirrortype}}
\define@key[psset]{optexp}{mirrordepth}{\edef\POK@mirror@depth{#1}}
\define@key[psset]{optexp}{mirrorradius}{\edef\POK@mirror@radius{#1}}
\define@boolkey[psset]{optexp}[POE@]{variable}[true]{}
%
% Grid
\define@key[psset]{optexp}{optgridcount}{\edef\POK@optgrid@count{#1}}
\define@key[psset]{optexp}{optgridwidth}{\edef\POK@optgrid@width{#1}}
\define@key[psset]{optexp}{optgridheight}{\edef\POK@optgrid@height{#1}}
\define@choicekey+[psset]{optexp}{optgridtype}[\val\nr]{binary,blazed}%
   {\edef\POK@optgrid@type{#1}}
   {\PackageError{pst-optexp}{Unknown value '\val' for optgridtype}}
\define@key[psset]{optexp}{optgriddepth}{\edef\POK@optgrid@depth{#1}}
\define@key[psset]{optexp}{optgridlinewidth}{\edef\POK@optgrid@linewidth{#1}}
\define@boolkey[psset]{optexp}[POE@]{reverse}[true]{}
%
% Box
\define@key[psset]{optexp}{optboxwidth}{%
   \pssetlength\optboxwidth{#1}%
   \edef\POK@optbox@width{#1}%
}
\define@key[psset]{optexp}{optboxheight}{\edef\POK@optbox@height{#1}}
\define@boolkey[psset]{optexp}[POE@]{endbox}[true]{}
\define@key[psset]{optexp}{refractiveindex}{\edef\POK@optbox@n{#1}}
%
% Plate
\define@key[psset]{optexp}{platelinewidth}{\edef\POK@plate@linewidth{#1}}
\define@key[psset]{optexp}{plateheight}{\edef\POK@plate@height{#1}}
%
% Optical Retardation Plate
\define@key[psset]{optexp}{platewidth}{\edef\POK@plate@width{#1}}
%
% Detector
\define@key[psset]{optexp}{detsize}{\edef\POK@detector@size{#1}}
\define@choicekey+[psset]{optexp}{dettype}[\val\nr]{round,diode}%
   {\edef\POK@detector@type{\val}}
   {\PackageError{pst-optexp}{Unknown value '\val' for key dettype}}
%
% Polarization
\define@key[psset]{optexp}{polwidth}{%
   \edef\POK@polarization@size{#1}%
   \PackageWarning{pst-optexp}{polwidth is obsolete, use polsize instead}%
}
\define@key[psset]{optexp}{polsize}{\edef\POK@polarization@size{#1}}
\define@key[psset]{optexp}{pollinewidth}{\edef\POK@polarization@linewidth{#1}}
\define@choicekey+[psset]{optexp}{poltype}[\val\nr]{parallel,misc,perp,rcirc,lcirc}%
   {\edef\POK@pol@type{#1}}
   {\PackageError{pst-optexp}{Unknown value '\val' for key poltype}}
\define@key[psset]{optexp}{pol}{%
   \edef\POK@poltype{#1}%
   \PackageWarning{pst-optexp}{pol is obsolete, use poltype instead}%
}
%
% Optical Diode
\define@key[psset]{optexp}{optdiodesize}{\edef\POK@diode@size{#1}}
%
% Penta Prism
\define@key[psset]{optexp}{pentaprismsize}{\edef\POK@pentaprism@size{#1}}
%
% Right-Angle Prism
\define@key[psset]{optexp}{raprismsize}{\edef\POK@raprism@size{#1}}
%
% Prism
\define@key[psset]{optexp}{prismsize}{\edef\POK@prism@size{#1}}
\define@key[psset]{optexp}{prismangle}{\edef\POK@prism@angle{#1}}
%
% Dove Prism
\define@key[psset]{optexp}{doveprismsize}{\edef\POK@doveprism@size{#1}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Parameters for fiber-optical components
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Fiber
\define@key[psset]{optexp}{fiberloops}{\edef\POK@fiber@count{#1}}
\define@key[psset]{optexp}{fiberloopradius}{\edef\POK@fiber@radius{#1}}
\define@key[psset]{optexp}{fiberloopsep}{\edef\POK@fiber@sep{#1}}
%
% Filter
\define@key[psset]{optexp}{filtersize}{\edef\POK@filter@size{#1}}
\define@choicekey+[psset]{optexp}{filtertype}[\val\nr]{bandstop,bandpass}%
   {\edef\POK@filter@type{#1}}%
   {\PackageError{pst-optexp}{Unknown value '\val' for key filtertype}}
%
% Polarization controller
\define@key[psset]{optexp}{polcontrolsize}{\edef\POK@polcontrol@size{#1}}
%
% Optical amplifier
\define@key[psset]{optexp}{optampsize}{\edef\POK@optamp@size{#1}}
%
% Mach-Zehnder-Modulator
\define@key[psset]{optexp}{optmzmsize}{\edef\POK@optmzm@size{#1}}
%
% Isolator
\define@key[psset]{optexp}{isolatorsize}{\edef\POK@isolator@size{#1}}
%
% Fiber polarizer
\define@key[psset]{optexp}{fiberpolsize}{\edef\POK@fiberpol@size{#1}}
%
% Optical switch
\define@key[psset]{optexp}{switchsize}{\edef\POK@switch@size{#1}}
\define@choicekey+[psset]{optexp}{switchstyle}[\val\nr]{opened,closed}%
   {\edef\POK@switch@style{#1}}%
   {\PackageError{pst-optexp}{Unknown value '\val' for key switchstyle}}
%
% Fiber delay line
\define@key[psset]{optexp}{fdlsize}{\edef\POK@fdl@size{#1}}
%
% Fiber collimator 
\define@key[psset]{optexp}{fibercolsize}{\edef\POK@fibercol@size{#1}}
%
% Coupler
\define@key[psset]{optexp}{couplersize}{\edef\POK@coupler@size{#1}}
\define@key[psset]{optexp}{couplersep}{\edef\POK@coupler@sep{#1}}
\define@choicekey+[psset]{optexp}{couplertype}[\val\nr]{none,elliptic}%
   {\edef\POK@coupler@type{#1}}%
   {\PackageError{pst-optexp}{Unknown value '\val' for key couplertype}}
\define@key[psset]{optexp}{align}{\edef\POK@align{#1}}
%
%
\define@key[psset]{optexp}{compshift}{\edef\POK@comp@shift{#1}}
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Code for the extnode parameter (additional input node)
%
\define@key[psset]{optexp}{extnoden@me}{\edef\POK@extnode@name{#1}}
%
% (this part was copied and adapted from \psset@@ref from pstricks.tex)
\define@key[psset]{optexp}{extnode}{%
   \edef\POK@extnode{#1}%
   \ifx\@empty\POK@extnode\else
      \pst@expandafter\psset@@extnode{#1}\@empty,,\@nil
   \fi
}%
\def\POK@xref{0}%
\def\POK@yref{0}%
\def\psset@@extnode#1#2,#3,#4\@nil{%
  \def\POK@xref{0}%
  \def\POK@yref{0}%
  \ifx\@empty#3\@empty
    \@nameuse{getref@optexp@#1}%
    \@nameuse{getref@optexp@#2}%
  \else
    \pst@checknum{#1#2}\POK@xref%
    \pst@checknum{#3}\POK@yref%
  \fi}%
\def\getref@optexp@c{}%
\def\getref@optexp@t{\def\POK@yref{1}}%
\def\getref@optexp@b{\def\POK@yref{-1}}%
\def\getref@optexp@l{\def\POK@xref{-1}}%
\def\getref@optexp@r{\def\POK@xref{1}}%
%
%
\define@key[psset]{optexp}{rotateref}{%
   \def\pst@temp{#1}%
   \ifx\@empty\pst@temp\else
      \pst@expandafter\psset@@rotateref{#1}\@empty,,\@nil
   \fi
}%
\def\POK@rotate@xref{0}%
\def\POK@rotate@yref{0}%
\def\psset@@rotateref#1#2,#3,#4\@nil{%
  \def\POK@rotate@xref{0}%
  \def\POK@rotate@yref{0}%
  \ifx\@empty#3\@empty
    \@nameuse{getref@optexp@rotate@#1}%
    \@nameuse{getref@optexp@rotate@#2}%
  \else
    \pst@checknum{#1#2}\POK@rotate@xref%
    \pst@checknum{#3}\POK@rotate@yref%
  \fi}%
\def\getref@optexp@rotate@c{}%
\def\getref@optexp@rotate@t{\def\POK@rotate@yref{1}}%
\def\getref@optexp@rotate@b{\def\POK@rotate@yref{-1}}%
\def\getref@optexp@rotate@l{\def\POK@rotate@xref{-1}}%
\def\getref@optexp@rotate@r{\def\POK@rotate@xref{1}}%
%
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% THIS IS THE COMPLETE AND NEW CODE FOR ALL CONNECTIONS %%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
\define@key[psset]{optexp}{b@sicname}{%
   \edef\pst@temp{#1}%
   \ifx\pst@temp\@empty%
      \edef\POK@basicname{\POS@optexp@basicname@default}%
   \else%
      \edef\POK@basicname{#1\POS@optexp@basicname@postfix}%
   \fi%
}%
\def\POE@complist{}%
\g@addto@macro{\endpspicture}{\gdef\POE@complist{}}%
\define@key[psset]{optexp}{@compname}{%
   \edef\POK@compname{#1}%
   \psset{b@sicname=#1}%
   \psset{extnoden@me=#1\POS@optexp@extnode@postfix}%
   % check if compname was already defined
   \ifx\POK@compname\@empty\else
      \@expandtwoargs\in@{,#1,}{,\POE@complist,}%
      \ifin@
         \PackageWarning{pst-optexp}%
            {^^Jcompname '#1' already used. Previously defined nodes will be overwritten!^^J}%
      \else
         % Use definition of \XKV@addtolist@x with an \xdef instead of \edef in order
         % to keep the bookkeeping global
         \xdef\POE@complist{\POE@complist\ifx\POE@complist\@empty\else,\fi#1}%
      \fi
   \fi
}%
\define@key[psset]{optexp}{connjoin}{%
   \edef\pst@temp{#1}%
   \ifnum\pst@temp<0
       \POE@connjoinfalse
   \else\ifnum\pst@temp>2
       \POE@connjoinfalse
   \else
       \POE@connjointrue
       \edef\POK@connjoin{\pst@temp}
   \fi\fi
}%
\define@key[psset]{optexp}{conn}{%
   \edef\pst@tempg{#1}%
   \expandafter\psset@@conn\pst@tempg\@empty-\@empty\@nil
   \if@pst\else
      \pstrickserr{Bad connection specification: #1}\@ehpa
   \fi
}%
\def\psset@@conn#1-#2\@empty#3\@nil{%
  \@psttrue
  \def\next##1,#1-##2,##3\@nil{\def\pst@tempg{##2}}%
  \expandafter\next\pst@optexp@conntable,#1-#1,\@nil
  \@ifundefined{psoe@cs@in@\pst@tempg}%
    {\@pstfalse\def\psk@connIn{}}%
    {\edef\psk@connIn{psoe@cs@in@\pst@tempg}}%
  \@ifundefined{psoe@cs@out@#2}%
    {\@pstfalse\def\psk@connOut{}}%
    {\def\psk@connOut{psoe@cs@out@#2}}%
}%
\def\psk@connIn{}%
\def\psk@connOut{}%
% this is the conntable for the direct drawing of the connections
\def\pst@optexp@conntable{,o-o,i-i,f-f}%
%
\def\psoe@cs@out@{}%
\def\psoe@cs@in@{}%
\def\psoe@cs@in@o{\psline[style=Beam](\POS@optexp@basicname@default A)(\optexp@nodeA)}%
\def\psoe@cs@out@o{\psline[style=Beam](\optexp@nodeB)(\POS@optexp@basicname@default B)}%
\def\psoe@cs@in@f{%
   \pccurve[angleA=!\pst@optexpdict FiberAngleA end, 
            angleB=!\pst@optexpdict FiberAngleB end, 
            style=FiberIn](\POS@optexp@basicname@default A)(\optexp@nodeA)%
}%
\def\psoe@cs@out@f{%
   \pccurve[angleA=!\pst@optexpdict FiberAngleA end, 
            angleB=!\pst@optexpdict FiberAngleB end, 
            style=FiberOut](\optexp@nodeB)(\POS@optexp@basicname@default B)%
}%
\def\psoe@cs@in@i{%
   \def\pst@par{style=Beam}
   \begin@OpenObj
      \addto@pscode{%
         [
         \pst@optexpdict
            (\POK@basicname) false GetInternalBeamNodes 
            /N@\POS@optexp@basicname@default A tx@NodeDict begin load GetCenter end 
         end
      }%
      \psline@ii
}%
\def\psoe@cs@out@i{%
   \def\pst@par{style=Beam}
   \begin@OpenObj
      \addto@pscode{%
         [
         \pst@optexpdict
            /N@\POS@optexp@basicname@default B tx@NodeDict begin load GetCenter end 
            (\POK@basicname) false GetInternalBeamNodes 
         end
      }%
      \psline@ii
}%
%
% 
\def\drawbeam{%
   \def\conntable{,a-a,b-b,A-A,B-B}%
   \begingroup
   \psset{style=Beam}%
   \pst@object{drawbeam}
}%
\def\drawbeam@i#1#2{%
   \def\pst@tempA{\pst@optexp@getfirstchar#1\@nil}%
   \def\pst@tempB{\pst@optexp@getfirstchar#2\@nil}%
   \ifPOE@connjoin
      \psset{linejoin=\POK@connjoin}%
   \fi
   \begin@OpenObj%
   \if(\pst@tempB
      % second parameter is a node
      \pst@optexp@@getcoor#2
      \def\psk@connOut{pst@coor}%
   \else
      \pst@optexp@check@compname{#2}%
      \edef\POK@basicnameB{#2\POS@optexp@basicname@postfix}%
   \fi
   \if(\pst@tempA
   %   % first parameter is a node
      \pst@optexp@@getcoor#1%
      \def\psk@connIn{pst@coor}%
   \else
      \pst@optexp@check@compname{#1}%
      \edef\POK@basicnameA{#1\POS@optexp@basicname@postfix}%
   \fi
   \let\POK@basicname\POK@basicnameB
   \addto@pscode{[ \@nameuse{\psk@connOut}}%
   \let\POK@basicname\POK@basicnameA
   \addto@pscode{\@nameuse{\psk@connIn}}%
   \psline@ii
   \endgroup
\ignorespaces}%
%
\def\pst@optexp@check@compname#1{%
   % check if 'compname' is defined
   \@expandtwoargs\in@{,#1,}{,\POE@complist,}%
   \ifin@\else
      \PackageError{pst-optexp}{^^Jcompname '#1' undefined!^^J}
   \fi
}%
\def\pst@optexp@getfirstchar#1#2\@nil{#1}%
\def\pst@optexp@@getcoor(#1){%
  \pst@@getcoor{#1}%
\ignorespaces}%
%
% IN
\def\psoe@cs@in@a{tx@NodeDict begin /N@\POK@basicname 1 load GetCenter end }%
\def\psoe@cs@in@A{\pst@optexpdict (\POK@basicname) true GetInternalBeamNodes end }%
\def\psoe@cs@in@b{tx@NodeDict begin /N@\POK@basicname N load GetCenter end }%
\def\psoe@cs@in@B{\pst@optexpdict (\POK@basicname) false GetInternalBeamNodes end }%
%
% OUT
%
\def\psoe@cs@out@a{tx@NodeDict begin N@\POK@basicname 1 GetCenter end }%
\def\psoe@cs@out@A{\pst@optexpdict (\POK@basicname) false GetInternalBeamNodes end }%
\def\psoe@cs@out@b{tx@NodeDict begin N@\POK@basicname N GetCenter end }%
\def\psoe@cs@out@B{\pst@optexpdict (\POK@basicname) true GetInternalBeamNodes end }%
%
%
\define@choicekey[psset]{optexp}{beam}[\val\nr]{}[]{%
   \psset{conn=i-o}%
}
\define@choicekey[psset]{optexp}{fiber}[\val\nr]{}[]{%
   \psset{conn=f-f, fiber@=true}%
}
%
% The fiber@ parameter is for internal use only to allow using \pscustom and connjoin
% when drawing internal beams.
\define@boolkey[psset]{optexp}[POE@]{fiber@}[true]{}
\def\optexp@nodeA{\POK@basicname 1}%
\def\optexp@nodeB{\POK@basicname N}%
\def\optexp@node#1{\POK@basicname #1}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% END %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% BASIC MACROS
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
\def\pst@OptexpVerb#1{\pst@Verb{\pst@optexpdict #1 end }}%
\def\begin@OptexpObj{%
   \define@key[psset]{optexp}{compname}{\psset{@compname=##1}}
   \pst@killglue
   \begingroup
      \pst@OptexpVerb{InitOptexpComp}%
      \use@par
      % Usually the shift refers to the y-direction, shifting in x-direction
      % is done by 'abspos' or 'position'
      \let\POK@comp@Yshift\POK@comp@shift%
      \def\POK@comp@Xshift{0}%
}%
\def\begin@OptexpMultipole{%
   \begin@OptexpObj
   % for multipoles the default shifting is in x-direction
   \let\POK@comp@Xshift\POK@comp@shift%
   \def\POK@comp@Yshift{0}%
}%
\def\end@OptexpObj{%
      \pst@OptexpVerb{(\POS@optexp@basicname@default) (\POK@basicname) CloseOptexpComp}%
  \endgroup
  \ignorespaces%
}%
\let\end@OptexpDipole\end@OptexpObj
\let\end@OptexpMultipole\end@OptexpObj
%
% Command analog to addbefore@par which is defined in pstricks.tex
% addafter@par 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.
%
\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%
}%
\def\getCLWH{CLW \pst@number\psxunit 2 mul div\space}%
\def\getCLW{CLW \pst@number\psxunit div\space}%
% Define new node '#3' which is shifted by (#1) relative to an existing
% node '#2'
\def\defShiftedNode(#1)(#2)#3{%
     \pst@getcoor{#1}\pst@tempOrig%
     \pst@getcoor{#2}\pst@tempDiff%
     \pnode(!%
        \pst@tempDiff \pst@tempOrig
        3 -1 roll add \pst@number\psyunit div
        3 1 roll add \pst@number\psxunit div exch){#3}%
}%
%
% 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
%
\def\newOptexpDipole{\@ifnextchar[{\new@optexpdipole}{\new@optexpdipole[]}}
\def\newOptexpDipoleNolabel{\@ifnextchar[{\new@optexpdipolenolabel}{\new@optexpdipolenolabel[]}}
\def\newOptexpTripole{\@ifnextchar[{\new@optexptripole}{\new@optexptripole[]}}
\def\newOptexpFiberDipole{\@ifnextchar[{\new@optexpfiberdipole}{\new@optexpfiberdipole[]}}
\def\newOptexpFiberQuadrupole{\@ifnextchar[{\new@optexpfiberquadrupole}{\new@optexpfiberquadrupole[]}}
\def\new@optexpfiberdipole[#1]#2#3{%
   \new@optexpdipole[fiber,#1]{#2}{#3}%
}%
%
\def\draw@InternalConnections{%
   \ifPOE@endbox
      \@nameuse{\psk@connIn}
   \else
      \ifPOE@fiber@
         \@nameuse{\psk@connIn}
         \@nameuse{\psk@connOut}
      \else
         \ifPOE@connjoin
            \def\tmp@A{psoe@cs@in@i}%
            \ifx\tmp@A\psk@connIn
               \def\tmp@B{psoe@cs@out@o}
               \ifx\tmp@B\psk@connOut
                  \pscustom[style=Beam, linejoin=\POK@connjoin]{\@nameuse{\psk@connIn}\@nameuse{\psk@connOut}}%
               \else\ifx\@empty\psk@connOut
                  \pscustom[style=Beam, linejoin=\POK@connjoin]{\@nameuse{\psk@connIn}\@nameuse{\psk@connOut}}%
               \else
                  \@nameuse{\psk@connIn}\@nameuse{\psk@connOut}%
               \fi\fi
           \else
               \def\tmp@A{psoe@cs@out@i}%
               \ifx\tmp@A\psk@connOut
                  \def\tmp@B{psoe@cs@in@o}
                  \ifx\tmp@B\psk@connIn
                     \pscustom[style=Beam, linejoin=\POK@connjoin]{\@nameuse{\psk@connIn}\@nameuse{\psk@connOut}}%
                  \else\ifx\@empty\psk@connIn
                     \pscustom[style=Beam, linejoin=\POK@connjoin]{\@nameuse{\psk@connIn}\@nameuse{\psk@connOut}}%
                  \else
                     \@nameuse{\psk@connIn}\@nameuse{\psk@connOut}%
                  \fi\fi
               \else
                  \@nameuse{\psk@connIn}\@nameuse{\psk@connOut}%
               \fi
            \fi
         \else
            \@nameuse{\psk@connIn}\@nameuse{\psk@connOut}%
         \fi
      \fi
   \fi
}%
%
% Creates new macros ...@i and ...@ii which provide most code for the arrangement
% of the objects. A tempNode@Label is predefined as well as two internal nodes if compname is
% defined.
% ...@iii must be defined manually and should contain all the stroking code
\def\new@optexpdipole[#1]#2#3{%
   \@ifundefined{#2@i}{%
      \@namedef{#2}{\pst@object{#2}}%
      \expandafter\def\csname #2@i\endcsname(##1)(##2)##3{%
         \addbefore@par{#3}%
         \addafter@par{#1}%
         \pst@regNodes{##1}{##2}
         \begin@OptexpObj
            \pst@adjustTempNodes
            \pst@draw@component{##3}{\@nameuse{#2@ii}}
            % connect
            \draw@InternalConnections
         \end@OptexpObj
      }%
      \@namedef{#2@ii}{%
        \pnode(0,0){tempNode@Label}%
        \pnode(0,0){\optexp@nodeA}%
        \pnode(0,0){\optexp@nodeB}%
        \@nameuse{#2@iii}%
      }%
   }{%
     \@pstrickserr{OptExp dipole object `#2' already defined}\@eha}%
\ignorespaces}%
%
% Equivalent to new@optexdipole, only that objects without labels are created.
\def\new@optexpdipolenolabel[#1]#2#3{%
   \@ifundefined{#2@i}{%
      \@namedef{#2}{\pst@object{#2}}%
      \expandafter\def\csname #2@i\endcsname(##1)(##2){%
         \addbefore@par{#3}%
         \addafter@par{#1}%
         \pst@regNodes{##1}{##2}
         \begin@OptexpObj
            \pst@adjustTempNodes
            \pst@draw@component{}{\@nameuse{#2@ii}}
            % connect
            \draw@InternalConnections
         \end@OptexpObj
      }%
      \@namedef{#2@ii}{%
        \pnode(0,0){tempNode@Label}%
        \pnode(0,0){\optexp@nodeA}%
        \pnode(0,0){\optexp@nodeB}%
        \@nameuse{#2@iii}%
      }%
   }{%
     \@pstrickserr{OptExp dipole object `#2' already defined}\@eha}%
\ignorespaces}%
%
% Equivalent to new@optexpdipole for tripole objects.
\def\new@optexptripole[#1]#2#3{%
   \@ifundefined{#2@i}{%
      \@namedef{#2}{\pst@object{#2}}%
      \expandafter\def\csname #2@i\endcsname(##1)(##2)(##3)##4{%
         \addbefore@par{#3}%
         \addafter@par{ref@angle=180,#1}%
         \pst@calcNodes{##1}{##2}{##3}
         \begin@OptexpMultipole
            \pst@draw@component{##4}{\@nameuse{#2@ii}}
            % adjust tempNode@A and tempNode@B for the connections
            % \pnode(##1){tempNode@A}
            % \pnode(##3){tempNode@B}
            % check if node must be switched, therefore we implement this
            % directly as PS code
            \pst@getcoor{##1}\pst@tempA%
            \pst@getcoor{##3}\pst@tempB%
            \pst@Verb{%
               \pst@optexpdict
               tx@NodeDict begin
                   {\pst@tempA } false chirality 0 le { /N@tempNode@B }{ /N@tempNode@A } ifelse
                   10 {InitPnode } NewNode
                   {\pst@tempB } false chirality 0 le { /N@tempNode@A }{ /N@tempNode@B } ifelse
                   10 {InitPnode } NewNode
               end end
            }%
            \draw@InternalConnections
         \end@OptexpMultipole
      }%
      \@namedef{#2@ii}{%
        \pnode(0,0){tempNode@Label}%
        \pnode(0,0){\optexp@nodeA}%
        \pnode(0,0){\optexp@nodeB}%
        \@nameuse{#2@iii}%
      }%
   }{%
     \@pstrickserr{OptExp tripole object `#2' already defined}\@eha}%
\ignorespaces}%
%
% 
\def\new@optexpfiberquadrupole[#1]#2#3{%
   \@ifundefined{#2@i}{%
      \@namedef{#2}{\pst@object{#2}}%
      \expandafter\def\csname #2@i\endcsname(##1)(##2)(##3)(##4)##5{%
         \addbefore@par{#3}%
         \addafter@par{#1}%
         %
         \begin@OptexpObj
            %
            \ifx\POK@align\POS@optexp@top
               \pnode(##1){tempNode@A}
               \pnode(##3){tempNode@B}
            \else\ifx\POK@align\POS@optexp@bottom
               \pnode(##2){tempNode@A}
               \pnode(##4){tempNode@B}
            \else
               \pst@getcoor{##1}\pst@tempA%
               \pst@getcoor{##2}\pst@tempB%
               \pnode(!\pst@tempA\pst@number\psyunit div exch \pst@number\psxunit div exch
                       \pst@tempB\pst@number\psyunit div exch \pst@number\psxunit div exch 
                       \pst@optexpdict mwNode end){tempNode@A}
               \pst@getcoor{##3}\pst@tempA%
               \pst@getcoor{##4}\pst@tempB%
               \pnode(!\pst@tempA\pst@number\psyunit div exch \pst@number\psxunit div exch
                       \pst@tempB\pst@number\psyunit div exch \pst@number\psxunit div exch 
                       \pst@optexpdict mwNode end){tempNode@B}
            \fi\fi
            %
            \pst@draw@component{##5}{\@nameuse{#2@ii}}
            % 
            % connect the fibers
            \psset{angleA=! \pst@optexpdict FiberAngleA end,
                   angleB=! \pst@optexpdict FiberAngleB end}
            \pccurve[style=FiberIn1](##1)(tempNode@A@1)
            \pccurve[style=FiberIn2](##2)(tempNode@A@2)
            \pccurve[style=FiberOut1](tempNode@B@1)(##3)
            \pccurve[style=FiberOut2](tempNode@B@2)(##4)
         \end@OptexpObj
      }%
      \@namedef{#2@ii}{%
        \pnode(0,0){tempNode@Label}%
        \@nameuse{#2@iii}%
      }%
   }{%
     \@pstrickserr{OptExp fiber quadrupole object `#2' already defined}\@eha}%
\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Fiber tripole macros
% 
\def\wdmsplitter{\pst@object{wdmsplitter}}%
\def\wdmsplitter@i(#1)(#2)(#3)#4{%
   \begin@OptexpObj
      \pnode(#1){tempNode@A}
      \ifx\POK@align\POS@optexp@top
         \pnode(#2){tempNode@B}
      \else\ifx\POK@align\POS@optexp@bottom
         \pnode(#3){tempNode@B}
      \else
         \pst@getcoor{#2}\pst@tempA%
         \pst@getcoor{#3}\pst@tempB%
         \pnode(!\pst@tempA\pst@number\psyunit div exch \pst@number\psxunit div exch
                 \pst@tempB\pst@number\psyunit div exch \pst@number\psxunit div exch 
                 \pst@optexpdict mwNode end){tempNode@B}
      \fi\fi
      %
      \pst@draw@component{#4}\wdmsplitter@ii
      %
      % default connection angles
      \psset{angleA=! \pst@optexpdict FiberAngleA end,
             angleB=! \pst@optexpdict FiberAngleB end}
      % 
      % connect the fibers
      \pccurve[style=FiberIn](#1)(tempNode@A@)     
      \pccurve[style=FiberOut1](tempNode@B@1)(#2)
      \pccurve[style=FiberOut2](tempNode@B@2)(#3)
   \end@OptexpObj
}%
%
%
\def\wdmcoupler{\pst@object{wdmcoupler}}%
\def\wdmcoupler@i(#1)(#2)(#3)#4{%
   \begin@OptexpObj
      \pnode(#3){tempNode@B}
      \ifx\POK@align\POS@optexp@top
         \pnode(#1){tempNode@A}
      \else\ifx\POK@align\POS@optexp@bottom
         \pnode(#2){tempNode@A}
      \else
         \pst@getcoor{#1}\pst@tempA%
         \pst@getcoor{#2}\pst@tempB%
         \pnode(!\pst@tempA\pst@number\psyunit div exch \pst@number\psxunit div exch
                 \pst@tempB\pst@number\psyunit div exch \pst@number\psxunit div exch 
                 \pst@optexpdict mwNode end){tempNode@A}
      \fi\fi
      %
      \pst@draw@component{#4}\wdmcoupler@ii
      %
      % default connection angles
      \psset{angleA=! \pst@optexpdict FiberAngleA end,
             angleB=! \pst@optexpdict FiberAngleB end}
      % 
      % connect the fibers
      \pccurve[style=FiberOut](tempNode@B@)(#3)
      \pccurve[style=FiberIn1](#1)(tempNode@A@1)
      \pccurve[style=FiberIn2](#2)(tempNode@A@2)
   \end@OptexpObj
}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%   Some of the components need three points to be positioned. 
%   These are:
%
%       1. starting point of the beam (in the PS-Code: (XA,YA))
%       2. reflection point on the surface (XG, YG)
%       3. end point (XB,YB)
%
%  With these three points \pst@calcNodes calculates two new points 'tempNode@A' 
%  and 'tempNode@B', between which the component is placed by the macro 
%  \pst@draw@component in the way, that 'angle of incidence' == 'angle of deflection'
%  regarding the reflection surface (mirror, diagonal of the beamsplitter, 
%  grid etc.)
% 
\def\pst@calcNodes#1#2#3{{%
  \pst@getcoor{#1}\pst@tempa%
  \pst@getcoor{#2}\pst@tempb%
  \pst@getcoor{#3}\pst@tempc%
  \pnode(!%
     \pst@optexpdict
     \pst@tempa \pst@number\psyunit div exch \pst@number\psxunit div exch 
     \pst@tempc \pst@number\psyunit div exch \pst@number\psxunit div exch 
     \pst@tempb \pst@number\psyunit div exch \pst@number\psxunit div exch 
     calcNodes
     /ExchCoorSwitch 
     Y@A X@A neg Y@B X@B neg ExchCoor def
     X@A Y@A end){tempNode@A}%
  \pnode(! \pst@optexpdict X@B Y@B end){tempNode@B}%
}\ignorespaces}%
%
%
% 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.
%
\def\pst@regNodes#1#2{%
    \pnode(#1){tempNode@A}
    \pnode(#2){tempNode@B}
\ignorespaces}%
\def\pst@adjustTempNodes{%
    \pst@Verb{tx@NodeDict begin N@tempNode@A GetCenter N@tempNode@B GetCenter end
              \pst@optexpdict ExchCoor dup end
              {/@xref \POK@xref\space neg def /@yref \POK@yref\space neg def} 
              {/@xref \POK@xref\space def /@yref \POK@yref\space def} ifelse
              \pst@optexpdict /ExchCoorSwitch ED end
              tx@OptexpDict /chirality known not {\pst@optexpdict /chirality 1 def 
              end } if
    }%
\ignorespaces}%
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Some other usefuls macros
%
% 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.
%
\def\pst@defShiftedRotLabelNode(#1)#2#3#4{%
    \pst@getcoor{#1}\pst@tempDiff%
    \pnode(!%
       \pst@tempDiff /YDiff ED /XDiff ED %
         /N@#2 load GetCenter /YShifted ED /XShifted ED
         /rot@angle #4 \POK@label@refangle\space add def
         /XDiff@Rot rot@angle cos XDiff mul rot@angle sin YDiff mul add def
         /YDiff@Rot rot@angle cos YDiff mul rot@angle sin XDiff mul sub def
         XShifted XDiff@Rot add \pst@number\psxunit div
         YShifted YDiff@Rot add \pst@number\psyunit div neg
       ){#3}%
    % reset reference label to 0
    \psset{ref@angle=0}
}%
%
% Define a new node #3 that is shifted by (#1) 
% with respect to the existing node #2
\def\pst@defShiftedLabelNode(#1)#2#3{%
  \pst@defShiftedRotLabelNode(#1){#2}{#3}{0}%
}%
%
% Used to put the label for labelref=relative
%
\def\put@RelLabel#1{%
   \nput[labelsep=0]{\POK@label@angle}%
        {tempNode@LabelShifted}%
        {\rput[\POK@label@align](0,0){\POK@label@style #1}}%
}%
%
% Place the component in argument #1 and define a new node 'tempNode@LabelShifted'
% for positioning of the label
\def\put@Comp#1{%
   \rput(\POK@comp@Xshift,\POK@comp@Yshift){%
      #1%
      \pst@defShiftedRotLabelNode(0,\POK@label@offset)%
                           {tempNode@Label}%
                           {tempNode@LabelShifted}%
                           {\POK@label@angle}%
   }%
}%
%
% Positioning of the label depending on the reference coordinates.
% Needs possibly a previously defined node tempNode@LabelShifted which
% marks exactly the position of the label relative to the component.
% This is defined by calling \put@Comp.
% 
% Parameter 'labelref' which sets the reference coordinates can have 
% the values 
%   global   => labelangle rotates the label origin in global coordinate 
%               system, text is not rotated
%   relgrav  => labelangle rotates the label origin relativ to the local
%               coordinate system of the component, text is not rotated
%   relative => as relgrav but text is rotated together with object.
%
\def\put@Label#1{%
   \def\pst@temp{#1}%
   \ifx\pst@temp\@empty\else
   \ifx\POK@label@ref\POS@labelref@global
      %
      % global
      \nput[labelsep=\POK@label@offset]%
           {\POK@label@angle}%
           {tempNode@Label}%
           {\rput[\POK@label@align](0,0){\POK@label@style #1}}%
      %
   \else\ifx\POK@label@ref\POS@labelref@relgrav
      %
      % relgrav
      \rput[\POK@label@align](tempNode@LabelShifted){\POK@label@style #1}%
      %
   \else\ifx\POK@label@ref\POS@labelref@relative
      %
      % relative
      \begingroup
      %
      % Redefine InitNC only for positioning of the label with 
      % labelref=relative
      %
      \pst@def{InitNC}<       % kindly contributed by Herbert Voss
      /b ED /a ED % second and first node
      /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 % xA yA xB yB
        4 copy exch 4 -1 roll 2 copy gt % yA yB xB xA
%        4 copy pop exch pop le % xA xB
          { 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=]{tempNode@A}{tempNode@B}%
      % 
      % 
      \ifx\POK@position\@empty
         \ifx\POK@abspos\@empty
            \ncput[nrot=:U,npos=]{\put@RelLabel{#1}}
         \else
            \nlput[nrot=:U](tempNode@A)(tempNode@B){\POK@abspos}{\put@RelLabel{#1}}
         \fi
      \else
         \ncput[nrot=:U,npos=\POK@position]{\put@RelLabel{#1}}
      \fi
      %
      \endgroup
   \fi\fi\fi
   \fi
}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FREE-RAY COMPONENTS
%
% DIPOLES
%
\newOptexpDipole{lens}{}%
\newOptexpDipole{pinhole}{}%
\newOptexpDipole{crystal}{}%
\newOptexpDipoleNolabel{polarization}{}%
\newOptexpDipole{optbox}{}%
\newOptexpDipole{optplate}{}%
\newOptexpDipole{optretplate}{}%
\newOptexpDipole[endbox]{optdetector}{}%
\@ifundefined{PSTcircLoaded}{\newpsobject{detector}{optdetector}}{}{}%
\newOptexpDipole{optdiode}{}%
\newOptexpDipole{doveprism}{}%
%
% TRIPOLES
%
\newOptexpTripole{mirror}{}%
\newOptexpTripole[ref@angle=-135]{beamsplitter}{}%
\newOptexpTripole{optgrid}{}%
\newOptexpTripole[ref@angle=-135]{pentaprism}{}%
\newOptexpTripole[ref@angle=-135]{rightangleprism}{}%
\newOptexpTripole[ref@angle=-135]{optprism}{}%
%
% SPECIAL OBJECTS
%
\def\optdipole{\pst@object{optdipole}}
\def\optdipole@i(#1)(#2)#3#4{%
   \pst@regNodes{#1}{#2}
   \begin@OptexpObj
      \pst@adjustTempNodes
      \pst@draw@component{#4}{%
         \pnode(0,0){tempNode@Label}%
         \pnode(0,0){\optexp@nodeA}%
         \pnode(0,0){\optexp@nodeB}%
         #3
      }%
      \draw@InternalConnections
   \end@OptexpObj
}%
\def\opttripole{\pst@object{opttripole}}
\def\opttripole@i(#1)(#2)(#3)#4#5{%
   \pst@calcNodes{#1}{#2}{#3}
   \begin@OptexpMultipole
      \pst@draw@component{#5}{%
         \pnode(0,0){tempNode@Label}% 
         \pnode(0,0){\optexp@nodeA}% 
         \pnode(0,0){\optexp@nodeB}% 
         #4
      }%
      % adjust tempNode@A and tempNode@B for the connections
      % \pnode(##1){tempNode@A}
      % \pnode(##3){tempNode@B}
      % check if node must be switched, therefore we implement this
      % directly as PS code
      \pst@getcoor{#1}\pst@tempA%
      \pst@getcoor{#3}\pst@tempB%
      \pst@Verb{%
        \pst@optexpdict
         tx@NodeDict begin
            {\pst@tempA } false chirality 0 le { /N@tempNode@B }{ /N@tempNode@A } ifelse
             10 {InitPnode } NewNode
             {\pst@tempB } false chirality 0 le { /N@tempNode@A }{ /N@tempNode@B } ifelse
             10 {InitPnode } NewNode
         end end
      }%
      \draw@InternalConnections
   \end@OptexpMultipole
}%
\def\fibercollimator{\pst@object{fibercollimator}}
\def\fibercollimator@i(#1)(#2){%
   \addbefore@par{conn=o-f}
   \def\pst@tempA{#1}%        
   \def\pst@tempB{#2}%
   \def\pst@tempC{}%
   \def\pst@tempD{}%
   \pst@regNodes{\pst@tempA}{\pst@tempB}
   \pst@adjustTempNodes
   \@ifnextchar({\fibercollimator@ii}{\fibercollimator@iv}%
}%
%
\def\fibercollimator@ii(#1){%
   \def\pst@tempC{#1}%
   \@ifnextchar({\fibercollimator@iii}{\fibercollimator@iv}%
}%
%
\def\fibercollimator@iii(#1)#2{%
   \def\pst@tempD{#1}%
   \fibercollimator@iv{#2}%
}
\def\fibercollimator@iv#1{%
   \begin@OptexpObj
      \pst@draw@component{#1}{%
         \pnode(0,0){tempNode@Label}%
         \pnode(0,0){\optexp@nodeA}%
         \pnode(0,0){\optexp@nodeB}%
         \fibercollimator@v%
      }%
      \@nameuse{\psk@connIn}%
      \ifx\@empty\pst@tempC
         \@nameuse{\psk@connOut}%
      \else\ifx\@empty\pst@tempD
         \psbezier[style=FiberOut](\pst@tempC)(\pst@tempB)(\pst@tempB)(\optexp@nodeB)%
      \else
         \psbezier[style=FiberOut](\pst@tempD)(\pst@tempC)(\pst@tempB)(\optexp@nodeB)%
      \fi\fi
   \end@OptexpObj
}%
% \def\fibercollimator@i(#1)(#2){%
%    \addbefore@par{conn=o-f}
%    \def\pst@tempA{#1}%        
%    \def\pst@tempB{#2}%
%    \@ifnextchar({\fibercollimator@ii}{\fibercollimator@iii}%
% }%
% %
% \def\fibercollimator@ii(#1)#2{%
%    \pst@regNodes{\pst@tempA}{\pst@tempB}
%    \pst@adjustTempNodes
%    \begin@OptexpObj
%    \pst@draw@component{#2}{%
%       \pnode(0,0){tempNode@Label}%
%       \pnode(0,0){\optexp@nodeA}%
%       \pnode(0,0){\optexp@nodeB}%
%       \fibercollimator@iv%
%    }%
%       \@nameuse{\psk@connIn}%
%       \psbezier[style=FiberOut](#1)(\pst@tempB)(\pst@tempB)(\optexp@nodeB)%
%    \end@OptexpObj
% }%
% %
% \def\fibercollimator@iii#1{%
%    \pst@regNodes{\pst@tempA}{\pst@tempB}
%    \begin@OptexpObj
%       \pst@adjustTempNodes
%       \pst@draw@component{#1}{%
%          \pnode(0,0){tempNode@Label}%
%          \pnode(0,0){\optexp@nodeA}%
%          \pnode(0,0){\optexp@nodeB}%
%          \fibercollimator@iv%
%       }%
%       \@nameuse{\psk@connIn}%
%       \@nameuse{\psk@connOut}%
%    \end@OptexpObj
% }%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FIBER COMPONENTS
\newOptexpFiberDipole{optfiber}{}
\newOptexpFiberDipole{optamp}{}
\newOptexpFiberDipole{optmzm}{}
\newOptexpFiberDipole{optfilter}{}
\newOptexpFiberDipole{polcontrol}{}
\newOptexpFiberDipole{optisolator}{}
\newOptexpFiberDipole{optfiberpolarizer}{}
\newOptexpFiberDipole{optswitch}{}
\newOptexpFiberDipole{fiberdelayline}{}
\newOptexpFiberQuadrupole{optcoupler}{}
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% default settings
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\psset{%
% general
        position=\@empty
        ,abspos=\@empty
        ,angle=0
        ,rotateref=c
% lens
        ,lenswidth=0.2
        ,lensheight=1
        ,lenstype=\@empty
        ,lensradius=\@empty
        ,lensradiusleft=1
        ,lensradiusright=1
        ,thicklens=false
% pinhole
        ,phlinewidth=2\pslinewidth
        ,outerheight=1
        ,innerheight=0.1
% beamsplitter
        ,bssize=0.8
%        ,bsstyle=cube
% crystal
        ,crystalwidth=1.4
        ,crystalheight=0.6
        ,caxislength=0.6
        ,lampscale=0.3
% mirror
        ,mirrorwidth=1
        ,mirrordepth=0.1
        ,mirrorradius=0
        % can't use the \POS@mirror@type@plain macro as \define@choicekey
        % does not expand the list containing the alternatives
        ,mirrortype=plain
        ,mirrorlinewidth=2\pslinewidth
        ,variable=false
% optgrid
        ,optgridcount=10
        ,optgridwidth=1
        ,optgridheight=0.15
        ,optgriddepth=0.075
        ,optgridtype=blazed
        ,optgridlinewidth=0.7\pslinewidth
        ,reverse=false
% optbox
        ,optboxwidth=1.4
        ,optboxheight=0.8
        ,refractiveindex=\@empty
% optplate
        ,plateheight=1
        ,platelinewidth=2\pslinewidth
% optretplate
        ,platewidth=0.1
% detector
        ,detsize=0.8
        ,dettype=round
% polarization
        ,poltype=parallel
        ,polsize=0.6
        ,pollinewidth=0.7\pslinewidth
% optdiode
        ,optdiodesize=0.8
% pentaprism
        ,pentaprismsize=0.7
% rightangleprism
        ,raprismsize=1.5
% optprism
        ,prismsize=1
        ,prismangle=60
% doveprism
        ,doveprismsize=0.6
% label
        ,labeloffset=0.8
        ,labelangle=0
        ,labelstyle=\small
        ,labelalign=c
        ,labelref=relgrav
        ,ref@angle=0
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% fiber optics
        ,@compname=\@empty
        ,extnode=\@empty
        ,fiberloops=3
        ,fiberloopradius=0.4
        ,fiberloopsep=0.3
        ,optmzmsize=0.8
        ,optampsize=0.8
        ,filtersize=0.8
        ,filtertype=bandpass
        ,polcontrolsize=0.15
        ,isolatorsize=0.6
        ,fiberpolsize=0.6
        ,couplersize=0.2
        ,couplersep=0.05
        ,couplertype=elliptic
        ,switchsize=0.8
        ,switchstyle=opened
        ,fdlsize=0.6
        ,fibercolsize=0.3
        ,conn=-
        ,usefiberstyle=false
        ,bsstyle=cube
        ,compshift=0
        ,connjoin=1
}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% DRAW COMPONENTS
%
% This macro is called by every unit
%
\def\pst@draw@component#1#2{%
    %
    \def\@@comp{%
       #2
       \ifx\POK@extnode\@empty\else
          \pnode(! \pst@optexpdict ExtNode end){\POK@extnode@name}
       \fi
    }%
    \ifPOE@endbox%
       \ifx\POK@label@offset\@empty
          \psset{labeloffset=0}
       \fi
       \psset{position=1}%
    \fi%
    % 
    \ncline[linestyle=none,fillstyle=none,npos=]{tempNode@A}{tempNode@B}%
    % 
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
    % 
    % Positioning of the component
    % 
    \begingroup
    %   
    \psset{style=OptComp}
    % 
    % linestyle to use, if component should be marked as optional
    \ifPOE@component@optional
      \psset{style=OptionalStyle}%
    \fi
    % if parameter 'position' is given, use it for 'npos'
    \ifx\POK@position\@empty
    % 
    % then check if absolute positioning is wanted
        \ifx\POK@abspos\@empty
           \ncput[nrot=:U,npos=]{\put@Comp{\@@comp}}
        \else
           \nlput[nrot=:U](tempNode@A)(tempNode@B){\POK@abspos}{\put@Comp{\@@comp}}
        \fi
    \else
       \ncput[nrot=:U,npos=\POK@position]{\put@Comp{\@@comp}}
    \fi
    \endgroup
    %
    % Now put the label
    \ifPOE@label@innerlabel
       \ifdim\optboxwidth>0pt
          \psset{labeloffset=0, labelref=relative}
          \put@Label{\parbox{\optboxwidth}{#1}}%
       \else
          \put@Label{#1}%
       \fi
    \else
       \put@Label{#1}%
    \fi
    %
    % Show some special dots for debugging
    \ifPOE@debug@showoptdots
        \psdot[linecolor=red](tempNode@Label)
        \psdot[linecolor=red](tempNode@LabelShifted)
        \psdot[linecolor=black](tempNode@A)
        \psdot[linecolor=black](tempNode@B)
    \fi
    %
\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% IMPLEMENTATIONS OF ALL ...@iii MACROS
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% MIRROR
%
\def\mirror@iii{%
   \edef\@mirror@ht{\POK@mirror@width\space\pst@number\psyunit mul 2 div }%
   \edef\@mirror@dp{\POK@mirror@depth\space\pst@number\psxunit mul }%
   \edef\@mirror@r{\POK@mirror@radius\space\pst@number\psxunit mul }%
   \edef\@mirror@postcode{neg 5 -1 roll exch 5 2 roll 90 add exch 90 add exch ArcR }%
   \edef\@mirror@extpostcode{neg \@mirror@dp add 5 -1 roll exch 5 2 roll 90 add exch 90 add }%
   %
   %
   % concave mirrors
   %
   \ifdim\POK@mirror@radius pt<0pt
      % always draw the input plane
      \begin@OpenObj
      \addto@pscode{\pst@optexpdict \@mirror@ht \@mirror@r rightConcave \@mirror@postcode end}%
      \end@OpenObj
      \ifx\POK@mirror@type\POS@mirror@type@extended
         % 
         % extended concave mirror
         \psset{style=ExtendedMirror}
         \begin@ClosedObj
         \addto@pscode{\pst@optexpdict \@mirror@ht \@mirror@r rightConcave \@mirror@postcode  
            \@mirror@ht \@mirror@r rightConcave \@mirror@extpostcode arc
            closepath end}%
         \end@ClosedObj
      \fi
   %
   %
   % convex mirrors
   %
   \else\ifdim\POK@mirror@radius pt>0pt
      % always draw the input plane
      \begin@OpenObj
      \addto@pscode{\pst@optexpdict \@mirror@ht \@mirror@r rightConvex \@mirror@postcode end}%
      \end@OpenObj
      \ifx\POK@mirror@type\POS@mirror@type@extended
         % 
         % extended convex mirror
         \psset{style=ExtendedMirror}
         \begin@ClosedObj
         \addto@pscode{\pst@optexpdict \@mirror@ht \@mirror@r rightConvex \@mirror@postcode
            \@mirror@ht \@mirror@r rightConvex \@mirror@extpostcode arcn
            closepath end}%
         \end@ClosedObj
      \fi
   \else
      % 
      % plain mirror 
      %
      \edef\@m@wd{\POK@mirror@width\space 2 div }
      \ifPOE@variable
         \psarc[linewidth=0.8\pslinewidth,arrowinset=0,arrowscale=0.8]{<->}
            (! \@m@wd 0.4 sub 0){0.6}{-20}{20}
         \psarc[linewidth=0.8\pslinewidth,arrowinset=0,arrowscale=0.8]{<->}
            (! \@m@wd 0.4 sub neg 0){0.6}{160}{200}
     \fi
     \psline[linewidth=\POK@mirror@linewidth](! \@m@wd neg \getCLWH)(! \@m@wd \getCLWH)
     % 
     % mirrortype
     \ifx\POK@mirror@type\POS@mirror@type@piezo%
        % 
        % piezo
        \psframe[style=PiezoMirror,dimen=outer](! \@m@wd 4 div 0)(! \@m@wd -4 div \@m@wd 2.5 div)
        \ifx\POK@extnode\@empty
           \psbezier(! 0 \@m@wd 2.5 div)%
                    (! 0 \@m@wd 1.5 div)%
                    (! \@m@wd 2 div \@m@wd 2 div)%
                    (! \@m@wd 4 div \@m@wd)%
        \else
           \pst@Verb{/@@y0 \@m@wd 2.5 div def }%
        \fi
     \else\ifx\POK@mirror@type\POS@mirror@type@extended%
        % 
        % extended
        \psframe[style=ExtendedMirror]%
           (! \@m@wd neg \POK@mirror@depth\space )%
           (! \@m@wd 0)%
     \fi\fi
  \fi\fi
}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 
% LENS
%
\def\lens@iii{%
   %
   % use old lens code to maintain backward compatibility
   \ifx\POK@lens@type\@empty
   % NEW CODE!
   \begin@ClosedObj
   \edef\@lens@newwd{0\space}%
   \edef\@lens@wd{\POK@lens@width\space\pst@number\psxunit mul 2 div }%
   \edef\@lens@th{0}%
   \addto@pscode{%
      \pst@optexpdict 
      /@wd \POK@lens@width\space\pst@number\psxunit mul 2 div def
      /@ht \POK@lens@height\space\pst@number\psyunit mul 2 div def
      /@rL \POK@lens@radiusLeft\space\pst@number\psxunit mul def
      /@rR \POK@lens@radiusRight\space\pst@number\psxunit mul def
      /@th 0 def	
   }%
   % 
   % distinguish between all the different lens-combination possibilities
   % 
    \ifdim\POK@lens@radiusLeft pt=0pt\else
       % this takes the /a1 definition from the leftC* procedures
       % the macro is necessary for the outer nodes
       \edef\@lens@newwd{%
          \POK@lens@radiusLeft\space\POK@lens@height\space 2 div segLen
          \ifdim\POK@lens@radiusLeft pt<0pt
             0.5 mul
          \fi\space
       }%
       %
       \edef\@lens@th{\ifPOE@thicklens \POK@lens@width\space 2 div \else \POK@lens@radiusLeft\space\POK@lens@height\space 2 div segLen \fi}%
       \addto@pscode{%
         /@th \ifPOE@thicklens @wd \else @rL @ht segLen \fi def
         @ht @rL
         \ifdim\POK@lens@radiusLeft pt<0pt
            leftConcave
         \else
            leftConvex
         \fi
       }%
    \fi
    \ifdim\POK@lens@radiusRight pt=0pt\else
       % this takes the /a1 definition from the rightC* procedures
       % the macro is necessary for the outer nodes
       \edef\@lens@th{\@lens@th\space\ifPOE@thicklens \POK@lens@width\space 2 div\else \POK@lens@radiusRight\space\POK@lens@height\space 2 div segLen \fi\space add}%
       \addto@pscode{%
         /@th @th \ifPOE@thicklens @wd \else @rR @ht segLen \fi add def
         @ht @rR
         \ifdim\POK@lens@radiusRight pt<0pt
            rightConcave
         \else
            rightConvex
         \fi
       }%
    \fi
    % 
    % check some special cases
    % 
    % 1) Left is plain  -  right concave
    % \- right convex
    \ifdim\POK@lens@radiusLeft pt=0pt
       \ifdim\POK@lens@radiusRight pt=0pt\else
          \addto@pscode{%
             @th 2 div sub neg 5 1 roll
             @th 2 div neg @ht neg moveto ArcR
             @th 2 div neg @ht lineto
          }%
       \fi
    \fi
    % 
    % 
    % 2) Right is plain -  left concave
    % \- left convex
    \ifdim\POK@lens@radiusRight pt=0pt
       \ifdim\POK@lens@radiusLeft pt=0pt\else
          \addto@pscode{%
             @th 2 div sub 5 1 roll
             @th 2 div @ht moveto ArcL
             @th 2 div @ht neg lineto
          }%
       \fi
    \fi
    % 
    % 3) right and left are both curved
    \ifdim\POK@lens@radiusRight pt=0pt\else
       \ifdim\POK@lens@radiusLeft pt=0pt\else
          \addto@pscode{%
             @th 2 div dup
             7 1 roll sub neg 5 1 roll
             ArcR sub 5 1 roll ArcL
          }%
       \fi
    \fi
    % 
    % now complete the object
    \addto@pscode{closepath 1 setlinejoin end }%
    \pnode(! \pst@optexpdict\space\@lens@th\space -2 div 0 end){\optexp@nodeA}
    \pnode(! \pst@optexpdict\space\@lens@th\space 2 div 0 end){\optexp@nodeB}
    \end@ClosedObj
    %
    % OLD CODE (compatibility)
    \else
       \pst@draw@lens
   \fi
\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% LENS (old) maintained for backward compatibility
% used only if lensheight and lenswidth must be used to draw the lens 
% (i.e. when lensradius is not defined)
%
\def\pst@draw@lens{%
%
  \edef\@l@h{\POK@lens@height\space 2 div\space}%
  \edef\@l@a{\POK@lens@width\space 2 div\space}%
  % 
  \ifnum\POK@lens@type<3
  % CONVEX
     \ifx\POK@lens@radius\@empty
        \edef\@l@r{\@l@a 2 div \@l@h dup mul 2 \@l@a mul div add\space}%
     \else
        \edef\@l@r{\POK@lens@radius\space}%
        \edef\@l@a{\@l@r dup dup mul \@l@h dup mul sub sqrt sub\space}%
     \fi
     % 
     % define some parameters only for convex lenses
     \edef\@l@d{\@l@r \@l@a sub\space}%
     \edef\@l@alpha{\@l@h \@l@d atan\space}%
     \edef\@l@y{\@l@d\space}%
  \else
     % CONCAVE
     \ifx\POK@lens@radius\@empty
        \edef\@l@r{\@l@h 1.5 mul\space}%
     \else
        \edef\@l@r{\POK@lens@radius\space}%
     \fi%
     %
     % define some parameters only for concave lenses
     \edef\@l@d{\@l@r dup mul \@l@h dup mul sub sqrt\space}%
     \edef\@l@alpha{\@l@h \@l@d atan\space}%
     \edef\@l@y{\@l@r \@l@a add\space}%
  \fi%
  % 
  %
  \def\temp@LeftPlot{%
     \parametricplot[liftpen=1]{-1}{1}{%   
        \@l@r \@l@alpha t mul 180 add cos mul \@l@y add \@l@r \@l@alpha t mul 180 add sin mul}%
  }%
  \def\temp@RightPlot{%
     \parametricplot[liftpen=1]{-1}{1}{%  
        \@l@r \@l@alpha t mul cos mul \@l@y sub \@l@r \@l@alpha t mul sin mul}%
  }%      
  %
  %
  \pscustom{%
  \ifcase\POK@lens@type
     % plainconvex
     \temp@RightPlot%
     \closepath%
  \or
     % convexplain
     \temp@LeftPlot%
     \closepath%
  \or
     % biconvex
    \temp@LeftPlot%
     \temp@RightPlot%
     \closepath
  \or
     % plainconcave
     \temp@LeftPlot%
     \psline[liftpen=1](! 0 \@l@h neg)%
                       (! 0 \@l@h)%
                       (! \@l@r \@l@d sub \@l@a add \@l@h)%
     \closepath
  \or%
     % concaveplain
     \temp@RightPlot%
     \psline[liftpen=1](! 0 \@l@h)%
                       (! 0 \@l@h neg)%
                       (! \@l@r \@l@d sub \@l@a add neg \@l@h neg)%
     \closepath
  \or
     % biconcave
     \temp@RightPlot%
     \temp@LeftPlot%
     \closepath
  \fi
  }%
\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% PINHOLE
%
\def\pinhole@iii{%
  \psline[linewidth=\POK@pinhole@linewidth]%
         (! 0 \POK@pinhole@oheight\space 2 div)%
         (! 0 \POK@pinhole@iheight\space 2 div)%
  \psline[linewidth=\POK@pinhole@linewidth]%
         (! 0 \POK@pinhole@oheight\space -2 div)%
         (! 0 \POK@pinhole@iheight\space -2 div)%
\ignorespaces}
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% BEAMSPLITTER
%
\def\beamsplitter@iii{%
   \edef\@bs@wd{\POK@bssize\space 2.0 div\space}%
   \ifx\POK@bsstyle\POS@bs@cube
      \psline{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\POK@bsstyle\POS@bs@plate
      \psline(! \@bs@wd neg 2 sqrt mul 0)(! \@bs@wd 2 sqrt mul 0)
   \fi\fi
\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% CRYSTAL
%
\def\crystal@iii{%
   \pst@Verb{%
      /@@x \POK@crystal@width\space 0.5 mul def
      /@@y \POK@crystal@height\space 0.5 mul def
   }%
   \psrotate(! @@x \POK@rotate@xref\space mul @@y \POK@rotate@yref\space mul)
      {\POK@angle}{%
      \psframe(! @@x neg @@y neg)(! @@x @@y)
      \ifPOE@crystal@voltage%
         \psline(! @@x 4 div 3 mul neg @@y)%
                (! @@x 4 div 3 mul neg @@y 0.2 add)
         \pscircle[fillstyle=solid,%
                   fillcolor=white](! @@x 4 div 3 mul neg @@y 0.2 add){0.04}
         \psline(! @@x 4 div 3 mul neg @@y neg)%
                (! @@x 4 div 3 mul neg @@y neg 0.2 sub)%
         \psline(! @@x 4 div 3 mul neg 0.15 sub @@y neg 0.2 sub)%
                (! @@x 4 div 3 mul neg 0.15 add @@y neg 0.2 sub)%
      \fi
      % 
      \ifPOE@crystal@lamp
         \rput{180}(! @@x @@y 1.4 \POK@lamp@scale\space mul add){\crystal@lamp}%
      \fi
      % plot c-axis only, if caxislength > 0
      \ifdim\POK@crystal@caxislength pt>0pt
         \edef\@c@caxisL{\POK@crystal@caxislength\space 2 div\space}%
         \ifPOE@crystal@caxisinv
            %
            % invert the c-axis
            \psline[linestyle=dashed,%
                    dash=2pt 2pt,%
                    linewidth=0.7\pslinewidth,%
                    arrowinset=0]{->}%
                   (! 0 @@y neg)(! 0 @@y \@c@caxisL add)%
         \else
            \psline[linestyle=dashed,%
                    dash=2pt 2pt,%
                    linewidth=0.7\pslinewidth,%
                    arrowinset=0]{->}%
               (! 0 @@y)(! 0 @@y neg \@c@caxisL sub)%
         \fi
      \fi
      \pnode(0,0){tempNode@Label}
      \pnode(! @@x neg 0){\optexp@nodeA}
      \pnode(! @@x 
         \ifx\POK@optbox@n\@empty 0 \else
            \POK@angle\space sin neg dup dup mul neg \POK@optbox@n\space dup mul add sqrt div 2 @@x mul mul
         \fi
      ){\optexp@nodeB}
      %\pnode(! \@c@wd neg 0){\optexp@nodeA}
      %\pnode(! \@c@wd 0){\optexp@nodeB}
   }%
\ignorespaces}%
%
% LAMP FOR THE CRYSTAL
%
\def\crystal@lamp{%
  \psset{linewidth=0.6\pslinewidth}
  \edef\@l@s{\POK@lamp@scale\space}%
  % 
  \pscurve[fillstyle=none](! -0.05 \@l@s mul 0)%
          (! -0.1 \@l@s mul 0.15 \@l@s mul)%
          (! -0.2 \@l@s mul 0.25 \@l@s mul)%
          (! -0.25 \@l@s mul 0.5 \@l@s mul)%
          (! 0 0.7 \@l@s mul)%
          (! 0.25 \@l@s mul 0.5 \@l@s mul)%
          (! 0.2 \@l@s mul 0.25 \@l@s mul)%
          (! 0.1 \@l@s mul 0.15 \@l@s mul)%
          (! 0.05 \@l@s mul 0)
  \multido{\i=-210+40}{7}{%
    \rput{\i}(! 0 0.45 \@l@s mul){\psline(! -0.35 \@l@s mul 0)(! -0.6 \@l@s mul 0)}
  }
\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% POLARIZATION
%
\def\polarization@iii{%
%
  \edef\@pol@size{\POK@polarization@size\space 2 div\space}%
  \ifx\POK@pol@type\POS@pol@polparallel
     \psline[linestyle=solid,linewidth=\POK@polarization@linewidth,arrowscale=0.8]{<->}%
        (! 0 \@pol@size neg)(! 0 \@pol@size)%
  \fi
  \ifx\POK@pol@type\POS@pol@polperp
     \psdot[dotsize=0.05](0,0)%
     \pscircle[fillstyle=none,linestyle=solid,linewidth=\POK@polarization@linewidth](0,0){0.12}%
  \fi
  \ifx\POK@pol@type\POS@pol@polmisc
     \psline[linestyle=solid,linewidth=\POK@polarization@linewidth,arrowscale=0.8]{<->}%
        (! 0 \@pol@size neg)(! 0 \@pol@size)%
     \psdot[dotsize=0.05](0,0)%
     \pscircle[fillstyle=none,linestyle=solid,linewidth=0.7\pslinewidth](0,0){0.12}%
  \fi
  \ifx\POK@pol@type\POS@pol@polrcirc
     \psellipticarc[linewidth=\POK@polarization@linewidth]{->}%
        (0,0)(! \@pol@size 2 div \@pol@size){20}{-20}%
  \fi
  \ifx\POK@pol@type\POS@pol@pollcirc
     \psellipticarc[linewidth=\POK@polarization@linewidth]{<-}%
        (0,0)(! \@pol@size 2 div \@pol@size){20}{-20}
  \fi
\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% OPTICAL GRID
%
\def\optgrid@iii{%
   \edef\@g@cnt{\POK@optgrid@count\space}%
   \edef\@g@wd{\POK@optgrid@width\space 2 div\space}%
   \edef\@g@ht{\POK@optgrid@height\space}%
   \edef\@g@dp{\POK@optgrid@depth\space}%
   \edef\@g@step{\POK@optgrid@width\space\@g@cnt div\space}%
   \ifx\POK@optgrid@type\POS@optgrid@type@blazed
      \ifPOE@reverse%
         \pscustom[linewidth=\POK@optgrid@linewidth, linejoin=1]{%
            \psline[liftpen=1](! \@g@wd \@g@dp)(! \@g@wd \@g@ht)%
                              (! \@g@wd neg \@g@ht)(! \@g@wd neg \@g@dp)
            \multido{\i=0+1}{\POK@optgrid@count}{%
               \psline[liftpen=1](! \@g@wd neg \i\space \@g@step mul add \@g@dp)%
                                 (! \@g@wd neg \i\space \@g@step mul add 0)%
                                 (! \@g@wd neg \i\space 1 add \@g@step mul add \@g@dp)%
            }%
            \closepath
         }%
      \else%   
         \pscustom[linewidth=\POK@optgrid@linewidth, linejoin=1]{%
            \psline[liftpen=1](! \@g@wd \@g@dp)(! \@g@wd \@g@ht)%
                              (! \@g@wd neg \@g@ht)(! \@g@wd neg \@g@dp)
            \multido{\i=0+1}{\POK@optgrid@count}{%
               \psline[liftpen=1](! \@g@wd neg \i\space \@g@step mul add \@g@dp)%
                                 (! \@g@wd neg \i\space 1 add \@g@step mul add 0)%
                                 (! \@g@wd neg \i\space 1 add \@g@step mul add \@g@dp)%
            }%
            \closepath
         }%
      \fi%
   \else\ifx\POK@optgrid@type\POS@optgrid@type@binary
      \pscustom[linewidth=\POK@optgrid@linewidth]{%
         \psline[liftpen=1](! \@g@wd \@g@dp)(! \@g@wd \@g@ht)%
                           (! \@g@wd neg \@g@ht)(! \@g@wd neg \@g@dp)
         \multido{\i=0+1}{\POK@optgrid@count}{%
            \psline[liftpen=1](! \@g@wd neg \i\space \@g@step mul add \@g@dp)%
                              (! \@g@wd neg \i\space \@g@step mul add 0)%
                              (! \@g@wd neg \i\space 0.5 add \@g@step mul add 0)%
                              (! \@g@wd neg \i\space 0.5 add \@g@step mul add \@g@dp)%
                              (! \@g@wd neg \i\space 1 add \@g@step mul add \@g@dp)%
         }%
      }%
   \fi\fi
\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% OPTBOX
%
\def\optbox@iii{%
   \pst@Verb{%
      /@@x \POK@optbox@width\space 0.5 mul def
      /@@y \POK@optbox@height\space 0.5 mul def
   }%
   \ifPOE@endbox
      \pst@Verb{/@@x0 @@x def}%
      \psrotate(! @@x0 @@x \POK@rotate@xref\space mul add
                  @@y0 @@y \POK@rotate@yref\space mul add){\POK@angle}{%
         \pnode(! @@x 0){tempNode@Label}%
         \psframe[dimen=outer](! 0 @@y neg)(! @@x 2 mul @@y)
         \pnode(tempNode@B){\optexp@nodeA}
      }%
   \else
      \psrotate(! @@x0 @@x \POK@rotate@xref\space mul add
                  @@y0 @@y \POK@rotate@yref\space mul add){\POK@angle}{%
         \pnode(! @@x neg 0){\optexp@nodeA}
         \pnode(! @@x 
            \ifx\POK@optbox@n\@empty 0 \else
               \POK@angle\space sin neg dup dup mul neg \POK@optbox@n\space dup mul add sqrt div 2 @@x mul mul
            \fi
         ){\optexp@nodeB}   
         \pnode(0,0){tempNode@Label}
         \psframe[dimen=outer](! @@x neg @@y neg)(! @@x @@y)
      }%
   \fi
\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% OPTPLATE
%
\def\optplate@iii{%
   \psline[linewidth=\POK@plate@linewidth]%
          (! \POK@plate@height\space 2 div \POK@angle\space 2 copy sin mul 3 1 roll cos mul neg)%
          (! \POK@plate@height\space 2 div \POK@angle\space 2 copy sin mul neg 3 1 roll cos mul )%
\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% DETECTOR
%
\def\optdetector@iii{%
   \pnode(tempNode@B){\optexp@nodeA}
   \ifx\POK@detector@type\POS@detector@round
      \pnode(! \POK@detector@size\space .2 mul 0){tempNode@Label}%
      \begin@ClosedObj
         % I could have use pswedge but then a correction of the component size
         % depending on the current linewidth is not possible
         \addto@pscode{CLW 0.5 mul 0 \POK@detector@size\space\pst@number\psrunit mul 0.5 mul 
            CLW sub -90 90 arc closepath }%
      \end@ClosedObj
      \pst@Verb{/@@x0 \POK@detector@size\space 0.5 mul def}%
   \else\ifx\POK@detector@type\POS@detector@diode
      \edef\@sz{\POK@detector@size\space 0.5 mul\space}%
      \psframe[dimen=outer](! 0 \@sz neg)(!\@sz 2 mul \@sz)
      \pspolygon(! \@sz 0.8 mul \@sz -0.4 mul)%
             (! \@sz 1.6 mul \@sz -0.4 mul)%
             (! \@sz 1.2 mul \@sz 0.4 mul)%
      \psline(! \@sz 0.8 mul \@sz 0.4 mul \getCLWH add)(! \@sz 1.6 mul \@sz 0.4 mul \getCLWH add)
      \psset{arrows=->, arrowinset=0, arrowscale=0.8}
      \psline(! \@sz 0.2 mul \@sz 0.6 mul)(! \@sz 0.7 mul \@sz 0.3 mul)
      \psline(! \@sz 0.2 mul \@sz 0.3 mul)(! \@sz 0.7 mul 0)
      \psline(! \@sz 0.2 mul 0)(! \@sz 0.7 mul \@sz -0.3 mul)
      \pst@Verb{/@@x0 \@sz def /@@x \@sz def /@@y \@sz def}%
      \pnode(! \@sz 0){tempNode@Label}
   \fi\fi
\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% OPTRETPLATE
%
\def\optretplate@iii{%
   \edef\@p@ht{\POK@plate@height\space 2 div\space}%
   \edef\@p@wd{\POK@plate@width\space 2 div\space}%
   \psframe(! \@p@wd neg \@p@ht neg)(! \@p@wd \@p@ht)
   \psline{cc-cc}(! \@p@wd neg \@p@ht)(! \@p@wd \@p@ht neg)
\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% OPTDIODE
%
\def\optdiode@iii{%
   \edef\@sz{\POK@diode@size\space}%
   \psframe[dimen=outer](! \@sz -0.5 mul dup)(!\@sz 0.5 mul dup)
   \pspolygon(! \@sz -0.2 mul \@sz -0.2 mul)
             (! \@sz -0.2 mul \@sz 0.2 mul)
             (! \@sz 0.2 mul 0)
   \psline(! \@sz 0.2 mul \getCLWH add \@sz 0.2 mul)(! \@sz 0.2 mul \getCLWH add \@sz -0.2 mul)
   \pnode(! \@sz -0.5 mul 0){\optexp@nodeA}
   \pnode(! \@sz 0.5 mul 0){\optexp@nodeB}
\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% DOVE PRISM
%
\def\doveprism@iii{%
   \edef\@ht{\POK@doveprism@size\space 0.5 mul\space}%
   \edef\@wd{\POK@doveprism@size\space 1.5 mul\space}%
   \pspolygon(! \@wd neg \@ht neg)%
             (! \@wd \@ht neg)%
             (! \@ht dup)%
             (! \@ht neg \@ht)%
   \pnode(!\@wd \@ht add -0.5 mul 0){\optexp@nodeA}
   \pnode(! 0 \@ht neg){\optexp@node{2}}
   \pnode(!\@wd \@ht add 0.5 mul 0){\optexp@nodeB}
\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% PENTA PRISM
%
\def\pentaprism@iii{%
   \edef\@pp@size{\POK@pentaprism@size\space}%
   \pscustom{%
      \psline(! \@pp@size 2 sqrt div 0)%
         (! \@pp@size 2 sqrt div 67.5 cos \@pp@size mul 67.5 sin div sub \@pp@size)%
         (! 67.5 cos \@pp@size mul 67.5 sin div \@pp@size 2 sqrt div sub \@pp@size)%
         (! \@pp@size 2 sqrt div neg 0)%
         (! 0 \@pp@size 2 sqrt div neg)%
      \closepath
   }%
   \pnode(! \@pp@size 2 sqrt div 67.5 cos \@pp@size mul 67.5 sin 2 mul div sub \@pp@size 2 div){\optexp@nodeA}%
   \pnode(! 67.5 cos \@pp@size mul 67.5 sin 2 mul div \@pp@size 2 sqrt div sub \@pp@size 2 div){\optexp@nodeB}%
}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% PRISM
%
\def\optprism@iii{%
   % 
%    \pst@Verb{%
%       /@sz \POK@prism@size\space def
%       /@alpha \POK@prism@angle\space 0.5 mul def 
%       /@hshift @sz 0.5 mul @alpha tan mul \pst@optexpdict OEangle end 0.5 mul tan div def
%    }%
%    \pspolygon(! @sz neg @alpha tan mul @sz -0.5 mul @hshift sub)
%              (! @sz @alpha tan mul @sz -0.5 mul @hshift sub)
%              (! 0 @sz 0.5 mul @hshift sub)
%    \pnode(! @sz -0.5 mul @alpha tan mul @hshift neg){\optexp@nodeA}
%    \pnode(! @sz 0.5 mul @alpha tan mul @hshift neg){\optexp@nodeB}
   \pst@Verb{%
      /@sz \POK@prism@size\space def
      /@alpha \POK@prism@angle\space 0.5 mul def 
      /@hshift @sz 0.6 mul @alpha tan mul \pst@optexpdict OEangle end 0.5 mul tan div def
   }%
   \pspolygon(! @sz neg @alpha tan mul @sz -0.4 mul @hshift sub)
             (! @sz @alpha tan mul @sz -0.4 mul @hshift sub)
             (! 0 @sz 0.6 mul @hshift sub)
   \pnode(! @sz -0.6 mul @alpha tan mul @hshift neg){\optexp@nodeA}
   \pnode(! @sz 0.6 mul @alpha tan mul @hshift neg){\optexp@nodeB}
}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% RIGHT-ANGLE PRISM
%
\def\rightangleprism@iii{%
   % 
   \pst@Verb{%
      /prism@size \POK@raprism@size\space 0.5 mul def 
      /h \pst@optexpdict OEangle 0.5 mul sin modA mul end def
   }%
   \pspolygon(! prism@size neg h \getCLW add prism@size sub)
             (! prism@size h \getCLW add prism@size sub)
             (! 0 h \getCLW 2 sqrt mul add)%
   \pnode(! h neg 0){\optexp@nodeA}
   \pnode(! h 0){\optexp@nodeB}
}%
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FIBER OPTICS
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FIBER
%
\def\optfiber@iii{%
   \edef\@f@cnt{\POK@fiber@count\space}%
   \edef\@f@r{\POK@fiber@radius\space}%
   \edef\@f@sep{\POK@fiber@sep\space}%
   \parametricplot[plotpoints=200,style=Fiber]{0}{1}{%
      t 360 mul \@f@cnt mul sin  \@f@r mul \@f@sep \@f@cnt 1 sub mul t 0.5 sub mul add
      1 t 360 mul \@f@cnt mul cos sub \@f@r mul
   }%
   \pnode(!\@f@sep \@f@cnt 1 sub mul \@f@r mul 0.5 mul neg 0){\optexp@nodeA}
   \pnode(!\@f@sep \@f@cnt 1 sub mul \@f@r mul 0.5 mul 0){\optexp@nodeB}
\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% OPTMZM
%
\def\optmzm@iii{%
   \pst@Verb{%
      /@@x \POK@optmzm@size\space 0.8 mul def
      /@@y \POK@optmzm@size\space 0.5 mul def
   }%
   \bgroup
      \ifPOE@usefiberstyle
         \psset{style=Fiber}
      \fi
      \psline(! @@x neg 0)(! @@x -0.7 mul 0)(! @@x -0.4 mul @@y 0.6 mul)%
             (! @@x 0.4 mul @@y 0.6 mul)(! @@x 0.7 mul 0)(! @@x 0)%
             (! @@x 0.7 mul 0)(! @@x 0.4 mul @@y -0.6 mul)%
             (! @@x -0.4 mul @@y -0.6 mul)(! @@x -0.7 mul 0)%
   \egroup
   \psframe[dimen=outer](! @@x neg @@y neg)(! @@x @@y)
   %
   \pnode(! @@x neg 0){\optexp@nodeA}
   \pnode(! @@x 0){\optexp@nodeB}
\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% OPTICAL FILTER
%
\def\optfilter@iii{%
   \pst@Verb{%
      /@@x \POK@filter@size\space 0.5 mul def
      /@@y @@x def
   }%
   \def\filter@curve{%
     \parametricplot[plotstyle=curve,arrows=c-c]{-1}{1}{%
       t @@x mul 0.7 mul t Pi mul RadtoDeg 90 add cos 0.2 @@x mul mul}%
   }%
   \psframe[dimen=outer](! @@x neg dup)(! @@x dup)
   \multips(! 0 -0.5 @@y mul)(! 0 0.5 @@y mul){3}{\filter@curve}
   \ifx\POK@filter@type\POS@filter@type@bandpass
      \psline(! -0.3 @@x mul -0.65 @@y mul)%
             (! 0.3 @@x mul -0.35 @@y mul)%
      \psline(! -0.3 @@x mul 0.35 @@y mul)%
             (! 0.3 @@x mul 0.65 @@y mul)%
      \rput(! 0 -0.5 @@y mul){\filter@curve}
      \rput(0, 0){%
         \ifPOE@usefiberstyle
            \psset{style=Fiber}
         \fi
         \filter@curve}
      \rput(! 0 0.5 @@y mul){\filter@curve}
   \else\ifx\POK@filter@type\POS@filter@type@bandstop
      \psline(! -0.3 @@x mul -0.15 @@y mul)%
             (! 0.3 @@x mul 0.15 @@y mul)%
      \rput(! 0 -0.5 @@y mul){%
         \ifPOE@usefiberstyle
            \psset{style=Fiber}
         \fi
         \filter@curve}
      \rput(0, 0){\filter@curve}
      \rput(! 0 0.5 @@y mul){%
         \ifPOE@usefiberstyle
            \psset{style=Fiber}
         \fi
         \filter@curve}
   \fi\fi
   %
   \pnode(! @@x neg 0){\optexp@nodeA}
   \pnode(! @@x 0){\optexp@nodeB}
\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% OPTICAL AMPLIFIER
%
\def\optamp@iii{%
   \edef\@sz{\POK@optamp@size\space 0.5 mul\space}%
   \edef\@xl{0.75 sqrt \@sz mul\space}%
   \pspolygon(! \@xl 0)(! \getCLWH \@xl sub \@sz)(! \getCLWH \@xl sub \@sz neg)
   \pnode(!\@xl neg 0){\optexp@nodeA}
   \pnode(!\@xl 0){\optexp@nodeB}
\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% POLARIZATION CONTROLLER
%
\def\polcontrol@iii{%
   \edef\@sz{\POK@polcontrol@size\space}%
   \ifPOE@usefiberstyle
      \psset{style=Fiber}
   \fi
   \multips(! -2.5 \@sz mul \@sz)(! 2.5 \@sz mul 0){3}{\pscircle(0,0){\POK@polcontrol@size}}
\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ISOLATOR
%
\def\optisolator@iii{%
   \edef\@ht{\POK@isolator@size\space 2 div\space}%
   \edef\@wd{\POK@isolator@size\space 0.8 mul\space}%
   \psframe[dimen=outer](! \@wd neg \@ht neg)(! \@wd \@ht)
   \psline[linewidth=2\pslinewidth,arrowinset=0]{->}(! \@wd neg 0.6 mul 0)(!\@wd 0.6 mul 0)
   \pnode(! \@wd neg 0){\optexp@nodeA}
   \pnode(! \@wd 0){\optexp@nodeB}
\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FIBER POLARIZER
%
\def\optfiberpolarizer@iii{%
   \edef\@ht{\POK@fiberpol@size\space 2 div\space}%
   \edef\@wd{\POK@fiberpol@size\space 0.8 mul\space}%
   \psframe[dimen=outer](! \@wd neg \@ht neg)(! \@wd \@ht)
   \psline(! \@wd neg 0.2 mul \@ht neg)(!\@wd 0.2 mul \@ht)
   \pnode(! \@wd neg 0){\optexp@nodeA}
   \pnode(! \@wd 0){\optexp@nodeB}
\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% SWITCH
%
\def\optswitch@iii{%
   \pst@Verb{%
      /@@x \POK@switch@size\space 0.5 mul def
      /@@y @@x def
   }%
   \pnode(! @@x neg 0){\optexp@nodeA}%
   \pnode(! @@x 0){\optexp@nodeB}%
   % storing the linewidth of the object allows for some aesthetic fine tuning 
   \pstVerb{tx@Dict begin /@lw \getCLW def end}%
   % the fiber parts
   \bgroup
      \ifPOE@usefiberstyle
         \psset{style=Fiber}
      \fi
      \psline[arrows=-](! @@x neg 0)(! @@x -0.6 mul @lw sub 0)%
      \psline[arrows=-](! @@x 0.6 mul 0)(! @@x 0)%
   \egroup
   % different styles
   \ifx\POK@switch@style\POS@optexp@closed%
      %
      \bgroup
      \ifPOE@usefiberstyle
         \psset{style=Fiber}
      \fi
      \psdot[dotsize=3\pslinewidth](! @@x 0.6 mul 0)%
      \psdot[dotsize=3\pslinewidth](! @@x -0.6 mul 0)%
      \psline[arrows=-, linewidth=1.5\pslinewidth](! @@x -0.6 mul @lw)(! @@x 0.6 mul @lw)%      
      \egroup
   \else
      \psline[arrows=-, linewidth=1.5\pslinewidth](! @@x -0.6 mul @lw add @lw)(! @@x 0.6 mul dup)%
      \pscircle(! @@x -0.6 mul 0){\pslinewidth}%
      \psdot[dotsize=3\pslinewidth](! @@x 0.6 mul 0)%
   \fi
   \psframe[dimen=outer](! @@x neg dup)(! @@x dup)%
\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FIBER DELAY LINE
%
\def\fiberdelayline@iii{%
   \pst@Verb{%
      /@@x \POK@fdl@size\space 0.8 mul def
      /@@y \POK@fdl@size\space 0.5 mul def
   }%
   \psframe[dimen=outer](! @@x neg @@y neg)(! @@x @@y)
   \psline{->}(! @@x -0.3 mul @@y -1.5 mul)(! @@x 0.3 mul @@y 1.7 mul)
   \pnode(! @@x neg 0){\optexp@nodeA}
   \pnode(! @@x 0){\optexp@nodeB}
\ignorespaces}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% COUPLER
%
\def\optcoupler@iii{%
   \edef\@sz{\POK@coupler@size\space}%
   \edef\@sep{\POK@coupler@sep\space 0.5 mul\space}%
   \ifx\POK@align\POS@optexp@top
      \pst@Verb{/@yshift \@sep neg def}%
   \else\ifx\POK@align\POS@optexp@bottom
      \pst@Verb{/@yshift \@sep def}%
   \else
      \pst@Verb{/@yshift 0 def}%
   \fi\fi
   \ifx\POK@coupler@type\POS@coupler@type@elliptic
      \psellipse[dimen=outer](!0 @yshift)(! \@sz \@sz 0.4 mul)
      \ifPOE@variable
         \psline[arrowinset=0]{->}(!\@sz -0.5 mul \@sz neg @yshift add)(!\@sz 0.5 mul \@sz @yshift add)
      \fi
      \pnode(! \@sz neg \getCLW 0.3 mul add @yshift \@sep add){tempNode@A@1}
      \pnode(! \@sz neg \getCLW 0.3 mul add @yshift \@sep sub){tempNode@A@2}
      \pnode(! \@sz \getCLW 0.3 mul sub @yshift \@sep add){tempNode@B@1}
      \pnode(! \@sz \getCLW 0.3 mul sub @yshift \@sep sub){tempNode@B@2}
      \pnode(! 0 @yshift){tempNode@Label}
   \else\ifx\POK@coupler@type\POS@coupler@type@none
      \pnode(! \@sz -0.5 mul @yshift \@sep add){tempNode@A@1}
      \pnode(! \@sz -0.5 mul @yshift \@sep sub){tempNode@A@2}
      \pnode(! \@sz 0.5 mul @yshift \@sep add){tempNode@B@1}
      \pnode(! \@sz 0.5 mul @yshift \@sep sub){tempNode@B@2}
      \psline[style=Fiber](tempNode@A@1)(tempNode@B@1)
      \psline[style=Fiber](tempNode@A@2)(tempNode@B@2)
   \fi\fi
}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% WDM COUPLER
%
\def\wdmcoupler@ii{%
   \edef\@sz{\POK@coupler@size\space}%
   \edef\@sep{\POK@coupler@sep\space 0.5 mul\space}%
   \ifx\POK@align\POS@optexp@top
      \pst@Verb{/@yshift \@sep neg def}%
   \else\ifx\POK@align\POS@optexp@bottom
      \pst@Verb{/@yshift \@sep def}%
   \else
      \pst@Verb{/@yshift 0 def}%
   \fi\fi
   \ifx\POK@coupler@type\POS@coupler@type@elliptic
      \psellipse[dimen=outer](!0 @yshift)(! \@sz \@sz 0.4 mul)
      \pnode(! \@sz neg \getCLW 0.3 mul add @yshift \@sep add){tempNode@A@1}
      \pnode(! \@sz neg \getCLW 0.3 mul add @yshift \@sep sub){tempNode@A@2}
      \pnode(!0 @yshift){tempNode@Label}
      \pnode(! \@sz \getCLW 0.3 mul sub 0){tempNode@B@}      
   \else\ifx\POK@coupler@type\POS@coupler@type@none
      \pnode(0,0){tempNode@A@1}
      \pnode(0,0){tempNode@A@2}
      \pnode(0,0){tempNode@B@}
      \pnode(0,0){tempNode@Label}
   \fi\fi
}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% WDM SPLITTER
%
\def\wdmsplitter@ii{%
   \edef\@sz{\POK@coupler@size\space}%
   \edef\@sep{\POK@coupler@sep\space 0.5 mul\space}%
   %
   \ifx\POK@align\POS@optexp@top
      \pst@Verb{/@yshift \@sep neg def}%
   \else\ifx\POK@align\POS@optexp@bottom
      \pst@Verb{/@yshift \@sep def}%
   \else
      \pst@Verb{/@yshift 0 def}%
   \fi\fi
   \ifx\POK@coupler@type\POS@coupler@type@elliptic
      \psellipse[dimen=outer](! 0 @yshift)(! \@sz \@sz 0.4 mul)
      \pnode(! \@sz neg \getCLW 0.3 mul add 0){tempNode@A@}
      \pnode(! \@sz \getCLW 0.3 mul sub @yshift \@sep add){tempNode@B@1}
      \pnode(! \@sz \getCLW 0.3 mul sub @yshift \@sep sub){tempNode@B@2}
      \pnode(! 0 @yshift){tempNode@Label}
   \else\ifx\POK@coupler@type\POS@coupler@type@none
      \pnode(0,0){tempNode@A@}
      \pnode(0,0){tempNode@B@1}
      \pnode(0,0){tempNode@B@2}
      \pnode(0,0){tempNode@Label}
   \fi\fi
}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% FIBER COLLIMATOR
%
\def\fibercollimator@v{%
   \def\@sz{\POK@fibercol@size\space 0.5 mul\space}%
   \pspolygon(! \@sz neg \getCLWH add \@sz neg)(!\@sz 0)(!\@sz neg \getCLWH add \@sz)
   \pnode(!\@sz neg 0){\optexp@nodeA}
   \pnode(!\@sz 0){\optexp@nodeB}
}%
%
%
\endinput
%

