mς
ώξbFc           @   sa   d  Z  d k Z e i d  Z d   Z d k l Z d k l Z d e f d     YZ	 [ [ d S(   sα  Description of decay processes.

Presently conceived as a specification of: if you put these things together,
with at least this much energy available, then you can get any one of the
following mixtures out, with various probabilities each.

Arguably should be described as: this reaction is characterised by a key
comprised of a bunch of quantum numbers, one of which is an activation energy;
here are several combinations of particles, each with an associated indication
of how far short of that activation energy it falls; each of which matches the
given quantum numbers; any of which can, given its activation energy defecit,
turn into any of the others, releasing however much energy their defecits differ
by.  Probably needs to be capable of coping with being told a temperature from
which to infer a distribution of available energy.

This last is really a description of a reaction, from which one should be able
to infer the equilibium mixture at any given temperature.  Note that actual
reaction rates do depend on how many particles are involved: if you really rely
on three things colliding, your rate is going to be *much* lower than a reaction
in which some two of those things can collide, forming an intermediate with a
modest half-life, during which this intermediate can run into the third party.

Description of reactions/decays is thus quite a subtle problem.  Which is my
excuse for the present implementation being over-simple ...

$Id: decay.py,v 1.5 2007/06/03 16:40:30 eddy Exp $
Ni   c         G   sL   t  d   | d  | t } t t | d  |   } t t |  f |  S(   s΅  As for a Decay, but does some pre-processing for you.

    Experiment yields the half-life of a thing that decays and the various modes
    of decay, each with its proportion of the whole.  This function
    pre-processes that data to produce the data Decay needs.

    First argument, source, is the thing that decays, a Particle.  Second is the
    half-life of this particle species.  Each subsequent argument is a sequence
    describing a single decay process: its first item is the proportion of
    decays that are of the type it describes; its second is an energy or None;
    all subsequent items are Particle()s produced by the decay.  The energy, if
    given, is the kinetic energy released by the decay: any photons produced
    should be described separately as particles.  The proportions merely need to
    be in the right ratio to one another: each will be divided by their total.

    Theory:

      A decay process with rate r is described by the probability distribution
        p(t) = r.exp(-r.t)
      for the time, t, at which the decay occurs.  The probability of decay
      before some specified time T is the integral of this from t=0 to t=T,
      namely 1-exp(-r.T), so the half-life is just log(2)/r.

      However, for several processes happening in parallel, we have a mapping
      ({rates}: r :{processes}) giving the several rates for the processes.
      Then the probability that decay happens after time T is exp(-r(i).T) for
      each process, i; assuming independence, the several processes then give
      product(: exp(-r(i).T) &larr;i :{processes}) which is just exp(-sum(r).T);
      the collective decay rate is the sum of the individual decay rates.  Thus
      we can infer sum(r) = log(2)/halflife.

      Equally, the proportion of decays that follow each of the processes is
      proportional to its rate.  Thus the rate for each process is just sum(r)
      times the proportion of decays that follow that process.
    c         C   s   |  | d S(   Ni    (   t   xt   y(   R    R   (    (    t'   /home/eddy/.sys/py/study/chemy/decay.pyt   <lambda>D   s    i    c         C   s   |  d | f t |  d  S(   Ni    i   (   t   pt   st   tuple(   R   R   (    (    R   R   E   s    N(
   t   reducet   procst   halflifet   _ln2t   scaleR   t   mapt   applyt   Decayt   source(   R   R	   R   R   (    (    R   t
   ratedDecay   s    # (   s   Lazy(   s   secondR   c           B   sH   t  Z d  Z d   Z d e f d     YZ e d  Z e i	 d  Z
 RS(   s:   Describes all the decays of some species of particle.
    c         G   sv   | |  _  g  d t } } x< | D]4 } | | d } | i t |  i	 | f |   q! Wt
 |  | |  _ |  _ d S(   s  Initialises a Decay description.

        First argument is what decays; this must be either a Particle() or a
        sequence whose members are either Particle()s or Quantity()s with units
        of energy; this first argument shall subsequently be accessible as
        self.source.

        Each subsequent argument (if any) is a sequence whose:

            * first member is a decay rate (the probability per unit time of the
              thing which decays doing this decay),

            * second member is the energy released (as kinetic energy - any
              photon energy should be included among the particles produced), or
              None (in which case the energy defecit between other yields and
              what decayed will be computed - no matter how bogusly), and

            * all subsequent members are decay products, which must be
              Particle()s, of the decay mode which, at the given rate, releases
              the given energy.

        Each such sequence is used to construct an object holding the decay rate
        as its .rate, the (possibly computed) energy as its .energy and the
        decay products as its .fragments, a tuple.  These objects (if any) will
        be accessible as the members of self.processes, a tuple.

        The overall rate of decay of self.source is provided by self.rate; it is
        simply the sum of the .rate attributes over self.processes. i    N(   R   t   selft   secondt   rowt   rateR   t   proct   appendR   t   _Decay__DecayR   t	   processes(   R   R   R   R   R   R   (    (    R   t   __init__O   s     	 $t   __Decayc           B   s#   t  Z d   Z d   Z d   Z RS(   Nc         G   s1   | | |  _  |  _ | d  j	 o | |  _ n d  S(   N(   R   t   bitsR   t   _Decay__bitst   energyt   None(   R   R   R   R   (    (    R   R   u   s     c         C   s   |  i i t d   |  i  S(   Nc         C   s   |  i S(   N(   R    R   (   R    (    (    R   R   z   s    (   R   R   R   R   R   (   R   t   ignored(    (    R   t   _lazy_get_energy_y   s    c         C   sL   h  |  i t d   |  i  } } x" |  i D] } | | i | | <q- W| S(   s   Mapping from particles emitted to likely kinetic energy.

            Assumes kinetic energy is distributed in proportion to rest mass. c         C   s   |  i S(   N(   R    t   mass(   R    (    (    R   R      s    N(   R   R   R   R   t   bokR   t   bitR!   (   R   R   R   R"   R#   (    (    R   t   _lazy_get_fragments_|   s     #
 (   t   __name__t
   __module__R   R    R$   (    (    (    R   R   t   s   		c         C   s   | |  i S(   N(   t   ln2R   R   (   R   R   R'   (    (    R   t   _lazy_get_halflife_   s    c         C   s   d | |  i |  S(   Ni   (   t   expR   R   t   when(   R   R*   R)   (    (    R   t   before   s    (   R%   R&   t   __doc__R   t   LazyR   R
   R(   t   mathR)   R+   (    (    (    R   R   K   s
    	%(
   R,   R.   t   logR
   R   t   study.snake.lazyR-   t   study.value.unitsR   R   (   R
   R-   R   R   R   R.   (    (    R   t   ?   s   		)A