Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

more/phys/ens.h

Go to the documentation of this file.
00001 //  Copyright (C) 2001--2002  Petter Urkedal (petter.urkedal@matfys.lth.se)
00002 //
00003 //  This file is free software; you can redistribute it and/or modify
00004 //  it under the terms of the GNU General Public License as published by
00005 //  the Free Software Foundation; either version 2 of the License, or
00006 //  (at your option) any later version.
00007 //
00008 //  This file is distributed in the hope that it will be useful,
00009 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 //  GNU General Public License for more details.
00012 //
00013 //  You should have received a copy of the GNU General Public License
00014 //  along with this program; if not, write to the Free Software
00015 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00016 //
00017 //  As a special exception, you may use this file as part of a free
00018 //  software library without restriction.  Specifically, if other files
00019 //  instantiate templates or use macros or inline functions from this
00020 //  file, or you compile this file and link it with other files to
00021 //  produce an executable, this file does not by itself cause the
00022 //  resulting executable to be covered by the GNU General Public
00023 //  License.  This exception does not however invalidate any other
00024 //  reasons why the executable file might be covered by the GNU General
00025 //  Public License.
00026 //
00027 //  $Id: ens.h,v 1.1 2002/05/30 18:01:40 petter_urkedal Exp $
00028 
00029 /** \file more/phys/ens.h
00030  **
00031  ** All type definitions and declarations of the \c more::phys::ens
00032  ** namespace. */
00033 
00034 
00035 #ifndef MORE_PHYS_ENS_H
00036 #define MORE_PHYS_ENS_H
00037 
00038 #include <more/math/qtypes.h>
00039 #include <more/phys/confidence_interval.h>
00040 #include <more/phys/nuclear.h>
00041 #include <more/phys/si.h>
00042 #include <more/io/syncstream.h>
00043 #include <more/sys/time.h>
00044 #include <more/sys/date.h>
00045 #include <more/gen/link.h>
00046 #include <more/gen/identifier.h>
00047 #include <more/diag/debug.h>
00048 #include <more/lang/stdint.h>
00049 #include <list>
00050 #include <set>
00051 #include <map>
00052 #include <vector>
00053 #include <string>
00054 #include <stdexcept>
00055 #include <memory>
00056 
00057 
00058 namespace more {
00059 namespace phys {
00060 namespace ens {
00061 
00062   //
00063   // Forward Declarations
00064   //
00065   class parser;
00066   class rec_ident;      // 1
00067   class rec_history;    // 2
00068   class rec_qvalue;     // 3
00069   class rec_xref;       // 4
00070   class rec_comment;    // 5
00071   class rec_parent;     // 6
00072   class rec_norm;       // 7
00073   class rec_pnorm;      // 8
00074   class rec_level;      // 9
00075   class rec_radiation;  // 10-14
00076   class rec_beta_mi;    //   10
00077   class rec_beta_pl;    //   11
00078   class rec_alpha;      //   12
00079   class rec_particle;   //   13
00080   class rec_gamma;      //   14
00081   class rec_ref;        // 15
00082 
00083   struct parse_error : std::runtime_error
00084   {
00085       parse_error(std::string what) : std::runtime_error(what) {}
00086   };
00087 
00088   //
00089   // Typedefs
00090   //
00091   typedef confidence_interval<double> confiv_t;
00092 
00093   enum fuzzy_bool_t {
00094       fuzzy_false = 0,
00095 //       fuzzy_most_improbable = 1,
00096 //       fuzzy_improbable = 2,
00097 //       fuzzy_possible = 3,
00098       fuzzy_probable = 4,
00099 //       fuzzy_most_probable = 5,
00100       fuzzy_true = 6,
00101       fuzzy_invalid = 7
00102   };
00103 
00104   // nucleus used for V1
00105   // std::string used for V2
00106 
00107   /** A reference to a publication. */
00108   struct citation_t                     // V3
00109   {
00110       /** Construct an invalid keynum. */
00111       citation_t() : m_year(0xffff) {}
00112 
00113       /** Construct an initialized keynum. */
00114       citation_t(int year, char* rest)
00115           : m_year(year)
00116       {
00117           std::copy(rest, rest+4, m_rest);
00118       }
00119 
00120       /** True if valid. */
00121       bool is_valid() const;
00122 
00123       /** Return the first part of the keynum, which in conventionally
00124        ** set to the year of the reference. */
00125       int year() const { return m_year; }
00126 
00127       /** Return a pointer to the first of the remaining 4 characters. */
00128       char const* rest_begin() const { return m_rest; }
00129 
00130       /** Return <tt>rest_begin() + 4</tt>. */
00131       char const* rest_end() const { return m_rest + 4; }
00132 
00133       /** True if \c *this and \c rhs are equal. */
00134       bool operator==(citation_t const& rhs) const
00135       {
00136           return m_year == rhs.m_year
00137               && m_rest[0] == rhs.m_rest[0]
00138               && m_rest[1] == rhs.m_rest[1]
00139               && m_rest[2] == rhs.m_rest[2]
00140               && m_rest[3] == rhs.m_rest[3];
00141       }
00142 
00143       void sync(io::syncstream&);
00144 
00145     private:
00146       unsigned short m_year;
00147       char m_rest[4];
00148   };
00149   std::istream& operator>>(std::istream&, citation_t&);
00150   std::ostream& operator<<(std::ostream&, citation_t const&);
00151 
00152   struct citation_list : std::list<citation_t> {};      // V3
00153   std::istream& operator>>(std::istream&, citation_list&);
00154   std::ostream& operator<<(std::ostream&, citation_list const&);
00155 
00156   struct publication_info_t             // V4
00157   {
00158       publication_info_t() {}
00159 
00160       explicit publication_info_t(std::string const& str) : m_str(str) {}
00161 
00162       std::string as_string() const { return m_str; }
00163 
00164       void sync(io::syncstream&);
00165 
00166     private:
00167       std::string m_str;
00168   };
00169 
00170   using sys::date;                      // V5
00171 
00172   enum record_kind_t                    // V6
00173   {
00174       record_kind_invalid,
00175       record_kind_none,
00176       record_kind_history,
00177       record_kind_norm,
00178       record_kind_pnorm, // note P in col 7
00179       record_kind_parent,
00180       record_kind_qvalue,
00181       record_kind_level,
00182       record_kind_gamma,
00183       record_kind_beta_mi,
00184       record_kind_beta_pl,
00185       record_kind_alpha,
00186       record_kind_reference,
00187       record_kind_xref,
00188       record_kind_particle,
00189       record_kind_dparticle
00190   };
00191   std::string record_kind_to_str(record_kind_t);
00192 
00193   inline std::ostream&
00194   operator<<(std::ostream& os, record_kind_t rk)
00195   {
00196       os << record_kind_to_str(rk);
00197       return os;
00198   }
00199 
00200   /** A set of comment refereces. */
00201   struct comment_refs_t                 // V8, FLAG
00202   {
00203       typedef std::vector<char>::const_iterator iterator;
00204       typedef std::vector<char>::const_iterator const_iterator;
00205 
00206       comment_refs_t() {}
00207       comment_refs_t(char const* beg, char const* end);
00208 
00209       iterator begin() const { return m_arr.begin(); }
00210       iterator end() const { return m_arr.end(); }
00211 
00212       bool empty() const { return m_arr.empty(); }
00213 
00214       void insert(char ch)
00215       {
00216           m_arr.push_back(ch);
00217           std::inplace_merge(m_arr.begin(), m_arr.end()-1, m_arr.end());
00218       }
00219 
00220       bool contains(char ch) const
00221       {
00222           return std::binary_search(begin(), end(), ch);
00223       }
00224 
00225       bool operator<(comment_refs_t const& rhs) const
00226       {
00227           return m_arr < rhs.m_arr;
00228       }
00229       bool operator==(comment_refs_t const& rhs) const
00230       {
00231           return m_arr == rhs.m_arr;
00232       }
00233 
00234       void sync(io::syncstream&);
00235 
00236     private:
00237       std::vector<char> m_arr;
00238   };
00239 
00240   // std::string used for V7
00241   // std::string used for V8
00242 
00243   /** Enumerator for kinds of particles. */
00244   enum particle_kind_t
00245   {
00246       particle_kind_invalid,
00247       particle_kind_none,
00248       particle_kind_neutron,    ///< The enumerator of a neutron
00249       particle_kind_proton,             ///< The enumerator of a proton
00250       particle_kind_alpha               ///< The enumerator of an α-particle
00251   };
00252 
00253   std::string particle_kind_to_str(particle_kind_t);
00254 
00255   inline std::ostream&
00256   operator<<(std::ostream& os, particle_kind_t pk)
00257   {
00258       os << particle_kind_to_str(pk);
00259       return os;
00260   }
00261 
00262   //   confiv_t used for V14
00263 
00264   struct multipolarity_t                // V19
00265   {
00266       // XXX to be refined
00267       multipolarity_t() {}
00268       explicit multipolarity_t(std::string const& str) : m_str(str) {}
00269 
00270       std::string as_string() const { return m_str; }
00271       bool is_known() const { return !m_str.empty(); }
00272 
00273       void sync(io::syncstream& sio);
00274 
00275     private:
00276       std::string m_str;
00277   };
00278 
00279   inline std::ostream&
00280   operator<<(std::ostream& os, multipolarity_t mult)
00281   {
00282       os << mult.as_string();
00283       return os;
00284   }
00285 
00286   struct ang_mom_xfer_elt
00287   {
00288       typedef unsigned int flags_t;
00289       static flags_t const flag_uncertain = 1;
00290       static flags_t const flag_assumed = 2;
00291       static flags_t const flag_upper_limit = 4;
00292       static flags_t const flag_lower_limit = 8;
00293       static flags_t const flag_magnetic = 16;
00294       static flags_t const flag_electric = 32;
00295       static flags_t const flags_unknown = 15;
00296 
00297       ang_mom_xfer_elt()
00298           : m_L(-1), m_flags(flags_unknown) {}
00299 
00300       ang_mom_xfer_elt(int L, flags_t fl)
00301           : m_L(L), m_flags(fl) {}
00302 
00303       int L() const { return m_L; }
00304       bool is_unknown() const { return m_flags == flags_unknown; }
00305       bool is_uncertain() const { return m_flags & flag_uncertain; }
00306       bool is_assumed() const { return m_flags & flag_assumed; }
00307       bool is_upper_limit() const { return m_flags & flag_upper_limit; }
00308       bool is_lower_limit() const { return m_flags & flag_lower_limit; }
00309       bool is_electric() const { return m_flags & flag_electric; }
00310       bool is_magnetic() const { return m_flags & flag_magnetic; }
00311 
00312       void sync(io::syncstream& sio);
00313 
00314       bool operator<(ang_mom_xfer_elt const& rhs) const
00315       {
00316           return m_L < rhs.m_L
00317               || m_L == rhs.m_L && m_flags < rhs.m_flags;
00318       }
00319       bool operator==(ang_mom_xfer_elt const& rhs) const
00320       {
00321           return m_L == rhs.m_L && m_flags == rhs.m_flags;
00322       }
00323 
00324     private:
00325       int m_L;
00326       flags_t m_flags;
00327   };
00328 
00329   struct ang_mom_xfer_set               // V22
00330       : std::set<ang_mom_xfer_elt>
00331   {
00332       void sync(io::syncstream& sio);
00333   };
00334 
00335   struct ang_mom_to_strength_map        // V21, V22
00336       : std::map<ang_mom_xfer_elt, confiv_t>
00337   {
00338       void sync(io::syncstream& sio);
00339   };
00340 
00341   /** An expression for possible spins and parities. */
00342   struct spin_parity_expr_t     // V20
00343   {
00344       // The J fields have a rather complex syntax which may require
00345       // an expression tree to fully represent.  The meaning of the
00346       // 'and' operator is unclear.  How the 'and', 'or' and 'to'
00347       // operators can be mixed is also unclear.
00348       spin_parity_expr_t() {}
00349 
00350       explicit spin_parity_expr_t(std::string const& str) : m_str(str) {}
00351 
00352       bool is_known() const { return !m_str.empty(); }
00353       std::string as_string() const { return m_str; }
00354       void sync(io::syncstream&);
00355 
00356     private:
00357       std::string m_str; // XXX temporary solution
00358   };
00359 
00360   typedef int energy_index_t;
00361   const energy_index_t energy_index_none = 0;
00362   const energy_index_t energy_index_sn = -1;
00363   const energy_index_t energy_index_sp = -2;
00364   const energy_index_t energy_index_sa = -3; // undocumented
00365   const int energy_index_bits = 6;
00366   void print_energy_ref(std::ostream& os, energy_index_t eref);
00367 
00368   /** The status of a level or radiation record. */
00369   enum rstatus_t  // The Q fields (= " ", "?", "S")
00370   {
00371       /** The entry is observed. */
00372       rstatus_observed,  // blank
00373       /** The entry is observed but uncertain. */
00374       rstatus_uncertain, // "?"
00375       /** The entry is not observed, but predicted or expected. */
00376       rstatus_predicted  // "S"
00377   };
00378 
00379   /** \internal */
00380   enum symbol_t {
00381       symbol_none,
00382       symbol_E,
00383       symbol_J,
00384       symbol_T,
00385       symbol_L,
00386       symbol_S,
00387       symbol_IB,
00388       symbol_IE,
00389       symbol_IA,
00390       symbol_TI,
00391       symbol_HF,
00392       symbol_LOGFT,
00393       symbol_UN
00394   };
00395 
00396   /** An unsigned int which is wide enough to store
00397    ** 2<sup><tt>sym</tt></sup> for any <tt>sym</tt> ∈
00398    ** <tt>symbol_t</tt>. */
00399   typedef lang::uint_least16_t symbol_intset_t;
00400 
00401   symbol_t str_to_symbol(std::string const&);
00402 
00403 
00404   //--------------------------------------------------------------------
00405   //                           Records
00406   //--------------------------------------------------------------------
00407 
00408   struct rec_commentable_base
00409   {
00410     private:
00411       typedef gen::link<rec_comment> comment_container;
00412     public:
00413       typedef comment_container::const_iterator comment_iterator;
00414 
00415       ~rec_commentable_base();
00416 
00417       comment_iterator comment_begin() const { return m_comments.begin(); }
00418       comment_iterator comment_end()   const { return m_comments.end(); }
00419 
00420       void dump_base(std::ostream&) const;
00421       void sync_base(io::syncstream&);
00422 
00423     private:
00424       comment_container m_comments; // comments for this rec
00425 
00426       friend class parser;
00427   };
00428 
00429   // 1. The Identification Record
00430   /** An ENSDF identification record. */
00431   struct rec_ident
00432   {
00433       void dump(std::ostream&) const;
00434       void sync(io::syncstream&);
00435 
00436       nucleus nucl() const { return m_nucid; }
00437       std::string const& dataset_id_string() const { return m_dsid; }
00438       citation_list const& citations() const { return m_dsref; }
00439       publication_info_t const& publication_info() const { return m_pub; }
00440       sys::date date_of_entry() const { return m_date; }
00441 
00442     private:
00443       nucleus                   m_nucid;
00444       std::string               m_dsid;
00445       citation_list             m_dsref;
00446       publication_info_t        m_pub;
00447       sys::date                 m_date;
00448 
00449       friend class parser;
00450   };
00451 
00452   // 2. The History Record
00453   /** An ENSDF history record. */
00454   struct rec_history : gen::linked
00455   {
00456       typedef std::list<std::string>::const_iterator keyless_iterator;
00457 
00458       void dump(std::ostream&) const;
00459       void sync(io::syncstream&);
00460 
00461       std::string const& type_of_change() const { return m_typ; }
00462       std::string const& author() const { return m_aut; }
00463       sys::date date_of_change() const { return m_dat; }
00464       sys::date literature_cutoff() const { return m_cut; }
00465       std::string const& citation() const { return m_cit; }
00466       std::string const& comments() const { return m_com; }
00467 
00468       std::pair<keyless_iterator, keyless_iterator>
00469       keyless_entries() const { return std::make_pair(m_keyless.begin(),
00470                                                       m_keyless.end()); }
00471 
00472     private:
00473       nucleus m_nucid;
00474 
00475       std::string       m_typ;
00476       std::string       m_aut;
00477       sys::date         m_dat;
00478       sys::date         m_cut;
00479       std::string       m_cit;
00480       std::string       m_com;
00481 
00482       std::list<std::string> m_keyless;
00483 //       std::map<std::string, std::string> m_entries;
00484 
00485       friend class parser;
00486   };
00487 
00488   // 3. The Q-value Record
00489   /** An ENSDF Q-value record. */
00490   struct rec_qvalue : rec_commentable_base
00491   {
00492       void dump(std::ostream&) const;
00493       void sync(io::syncstream&);
00494 
00495       confiv_t const& Q_mi() const { return m_qmi; }
00496       confiv_t const& S_n() const { return m_sn; }
00497       confiv_t const& S_p() const { return m_sp; }
00498       confiv_t const& S(math::pm_half mt) const {return mt==half?m_sp:m_sn;}
00499       confiv_t const& Q_alpha() const { return m_qa; }
00500       citation_list const& citations() const { return m_qref; }
00501 
00502     private:
00503       confiv_t          m_qmi;
00504       confiv_t          m_sn;
00505       confiv_t          m_sp;
00506       confiv_t          m_qa;
00507       citation_list     m_qref;
00508 
00509       friend class parser;
00510   };
00511 
00512   // 4. The Cross-Reference Record
00513   /** An ENSDF cross reference record. */
00514   struct rec_xref : gen::linked
00515   {
00516       void dump(std::ostream&) const;
00517       void sync(io::syncstream&);
00518 
00519       char dataset_symbol() const { return m_dssym; }
00520       std::string const& dataset_id() const { return m_dsid; }
00521 
00522     private:
00523       char              m_dssym;
00524       std::string       m_dsid;
00525 
00526       friend class parser;
00527   };
00528 
00529   // 5. The Comment Record
00530   /** An ENSDF comment record. */
00531   struct rec_comment : gen::linked
00532   {
00533       typedef std::map<gen::identifier, comment_refs_t>::const_iterator
00534               symflags_iterator;
00535 
00536       void dump(std::ostream&) const;
00537       void sync(io::syncstream&);
00538 
00539       record_kind_t rtype() const { return m_rtype; }
00540       particle_kind_t particle_kind() const { return m_psym; }
00541       bool is_preformatted() const { return !m_fill_p; }
00542       bool is_documentation() const { return m_doc_p; }
00543       std::string const& text() const { return m_ctext; }
00544 
00545     private:
00546       // Comment type C/D/T, General/Record/Footnote
00547       // Blank or record type of records to which the comment pertains
00548       record_kind_t     m_rtype;
00549       // Blank or symbol for a (delayed-)particle
00550       particle_kind_t   m_psym;
00551 //       symflag_list_type      m_symflags;
00552       std::map<gen::identifier, comment_refs_t> m_symflags;
00553       std::string       m_ctext;
00554       unsigned int      m_fill_p : 1;
00555       unsigned int      m_doc_p : 1;
00556 
00557       friend class parser;
00558   };
00559 
00560   // 6. The Parent Record
00561   /** An ENSDF parent record. */
00562   struct rec_parent : rec_commentable_base
00563   {
00564       void dump(std::ostream&) const;
00565       void sync(io::syncstream&);
00566 
00567     private:
00568       nucleus           m_nucid;
00569       confiv_t          m_E;
00570       energy_index_t    m_E_ref : energy_index_bits;
00571       spin_parity_expr_t        m_J;
00572       confiv_t          m_T;
00573       confiv_t          m_QP;
00574       //XXXchar         m_ion[4];
00575       unsigned int      m_T_as_width : 1;
00576 
00577       friend class parser;
00578   };
00579 
00580   // 7. The Normalization Record
00581   /** An ENSDF normalization record. */
00582   struct rec_norm : rec_commentable_base
00583   {
00584       void dump(std::ostream&) const;
00585       void sync(io::syncstream&);
00586 
00587       /** Normalization for photon intensity.  Multiplier for
00588        ** converting relation photon intensity \c
00589        ** rec_gamma::I_gamma_rel() to photons per decay of the parent
00590        ** through this decay branch or to photons per neutron captures
00591        ** in an (n, γ) reaction. */
00592       confiv_t const& mult_gamma_rel_branch() const { return m_nr; }
00593 
00594       /** Normalization of transition intensity.  Multiplier for
00595        ** converting relative transition intensity (including
00596        ** conversion electrons) \c rec::gamma::I_trans_rel() to
00597        ** transitions per decay of the parent through this decay
00598        ** branch or per neutron capture in an (n, γ) reaction. */
00599       confiv_t const& mult_trans_rel_branch() const { return m_nt; }
00600 
00601       /** Normalization of decay branches.  Multiplier for converting
00602        ** intensities from per decay of this branch to per decay of
00603        ** the parent nuclide.  */
00604       confiv_t const& mult_branch() const { return m_br; }
00605 
00606       /** Normalization of β± decay and EC.  Multiplier for converting
00607        ** \c rec_beta_mi::I_beta_mi_rel(), \c
00608        ** rec_beta_pl::I_beta_pl_rel() and \c rec_beta_pl::I_EC_rel()
00609        ** to intensities per decay through this decay branch. */
00610       confiv_t const& mult_beta_rel_branch() const { return m_nb; }
00611 
00612       /** Normalization of particle decay.  Multiplier for converting
00613        ** particle decay intensitis from per decay to per decay of
00614        ** precursor. */
00615       confiv_t const& mult_part() const { return m_np; }
00616 
00617     private:
00618       confiv_t m_nr;
00619       confiv_t m_nt;
00620       confiv_t m_br;
00621       confiv_t m_nb;
00622       confiv_t m_np;
00623 
00624       friend class parser;
00625   };
00626 
00627   // 8. The Production Normalization Record
00628   /** An ENSDF production normalization record. */
00629   struct rec_pnorm : rec_commentable_base
00630   {
00631       void dump(std::ostream&) const;
00632       void sync(io::syncstream&);
00633 
00634       /** Normalization of photon intensity.  Multiplier for
00635        ** converting relation photon intensity \c
00636        ** rec_gamma::I_gamma_rel() to photons per decay of the
00637        ** parent. */
00638       confiv_t const& mult_gamma() const { return m_nr_br; }
00639 
00640       /** Normalization of transition intensity.  Multiplier for
00641        ** converting relative transition intensity \c
00642        ** rec::gamma::I_trans_rel() to transitions per decay of the
00643        ** parent. */
00644       confiv_t const& mult_trans() const { return m_nt_br; }
00645 
00646       /** Normalization of β± decay and EC.  Multiplier for converting
00647        ** \c rec_beta_mi::I_beta_mi_rel(), \c
00648        ** rec_beta_pl::I_beta_pl_rel() and \c rec_beta_pl::I_EC_rel()
00649        ** to intensities per decay. */
00650       confiv_t const& mult_beta() const { return m_nb_br; }
00651 
00652       /** Normalization of particle decay.  Multiplier for converting
00653        ** particle decay intensitis from per decay to per decay of
00654        ** precursor. */
00655       confiv_t const& mult_part() const { return m_np; }
00656 
00657     private:
00658       confiv_t m_nr_br;
00659       confiv_t m_nt_br;
00660       confiv_t m_nb_br;
00661       confiv_t m_np;
00662 
00663       unsigned int m_com_opt : 3;
00664       // 0: Comment given in continuation record.
00665       // 1-7: Intensity and comment options.
00666 
00667       friend class parser;
00668   };
00669 
00670   // 9. The Level Record
00671   /** An ENSDF level record. */
00672   struct rec_level : gen::linked, rec_commentable_base
00673   {
00674       typedef gen::link<rec_radiation>::const_iterator  radiation_iterator;
00675 
00676       ~rec_level();
00677       void dump(std::ostream&) const;
00678       void sync(io::syncstream&);
00679 
00680       /** The status of observation. */
00681       rstatus_t status() const { return (rstatus_t)m_rstatus; }
00682 
00683       /** The energy relative to a given reference point. */
00684       confiv_t E_minus_E_ref() const { return m_E; }
00685 
00686       /** The index of the reference point energy. */
00687       energy_index_t i_E_ref() const { return m_E_ref; }
00688 
00689       /** Return the spin and parity specification. */
00690       spin_parity_expr_t const& Jpi() const { return m_J; }
00691 
00692       /** The half-life of the transition.  Not given if width() is
00693        ** given. */
00694       confiv_t T_half() const { return m_T_as_width?confiv_t():m_T; }
00695 
00696       /** The width of the transition.  Not given if T_half() is given. */
00697       confiv_t Gamma() const { return m_T_as_width?m_T:confiv_t(); }
00698 
00699       /* XXX m_LS */
00700 
00701       /** References to comments. */
00702       comment_refs_t const& comment_refs() const { return m_C; }
00703 
00704       /** First iterator in the range of radiation. */
00705       radiation_iterator radiation_begin() const
00706       {
00707           return m_radiations.begin();
00708       }
00709       /** Past end iterator in the range of radiations. */
00710       radiation_iterator radiation_end() const
00711       {
00712           return m_radiations.end();
00713       }
00714 
00715     private:
00716       confiv_t                  m_E;
00717       energy_index_t            m_E_ref : energy_index_bits;
00718       spin_parity_expr_t        m_J;
00719       confiv_t                  m_T;
00720       ang_mom_to_strength_map   m_LS;
00721       comment_refs_t            m_C;
00722 
00723       unsigned int m_MS : 4;   // V17
00724       // 0: blank, 1: M, 2: M1, 3: M2, ...
00725 
00726       unsigned int m_rstatus : 2;
00727       unsigned int m_T_as_width : 1;
00728 
00729       gen::link<rec_radiation> m_radiations;
00730 
00731       friend class parser;
00732   };
00733 
00734   // Base for 10–14.
00735   /** A base class for ENSDF radiation records. */
00736   struct rec_radiation : gen::linked, rec_commentable_base
00737   {
00738       void dump(std::ostream&) const;
00739       void dump_base(std::ostream&) const;
00740       void sync_base(io::syncstream&);
00741 
00742       /** The status of observation. */
00743       rstatus_t status() const { return (rstatus_t)m_rstatus; }
00744 
00745       /** The energy relative to a given reference point. */
00746       confiv_t E_minus_E_ref() const { return m_E; }
00747       /** The index of the reference point energy. */
00748       energy_index_t i_E_ref() const { return m_E_ref; }
00749 
00750       bool is_beta_mi() const { return m_sel == sel_beta_mi; }
00751       bool is_beta_pl() const { return m_sel == sel_beta_pl; }
00752       bool is_alpha() const { return m_sel == sel_alpha; }
00753       bool is_particle() const { return m_sel == sel_particle; }
00754       bool is_gamma() const { return m_sel == sel_gamma; }
00755 
00756       rec_beta_mi*      to_beta_mi();
00757       rec_beta_pl*      to_beta_pl();
00758       rec_alpha*        to_alpha();
00759       rec_particle*     to_particle();
00760       rec_gamma*        to_gamma();
00761 
00762       rec_beta_mi const*        to_beta_mi() const;
00763       rec_beta_pl const*        to_beta_pl() const;
00764       rec_alpha const*          to_alpha() const;
00765       rec_particle const*       to_particle() const;
00766       rec_gamma const*          to_gamma() const;
00767 
00768       static void do_delete(rec_radiation*);
00769 
00770     protected:
00771       enum selector
00772       {
00773           sel_beta_mi,
00774           sel_beta_pl,
00775           sel_alpha,
00776           sel_particle,
00777           sel_gamma
00778       };
00779 
00780       rec_radiation(selector sel) : m_sel(sel) {}
00781 
00782     private:
00783       selector          m_sel;
00784       confiv_t          m_E;
00785       energy_index_t    m_E_ref : energy_index_bits;
00786     protected:
00787       confiv_t          m_IX; // V13 21..29: multi-purpose
00788     private:
00789       comment_refs_t    m_C;  // V8
00790 
00791       unsigned int m_rstatus : 2;
00792 
00793       friend class dataset;
00794       friend class parser;
00795   };
00796 
00797   // 10. The Beta (β-) Record
00798   /** An ENSDF β- decay record. */
00799   struct rec_beta_mi : rec_radiation
00800   {
00801       void dump(std::ostream&) const;
00802       void sync(io::syncstream&);
00803 
00804       int  forbiddenness()           const { return m_un_forbiddenness; }
00805       bool forbiddenness_is_unique() const { return m_un_unique; }
00806 
00807       /** The β- intensity.  The unit in given in the normalization
00808        ** record. */
00809       confiv_t const& I_beta_mi_rel() const { return m_IX; }
00810 
00811       /** The log(<i>ft</i>) value. */
00812       confiv_t const& log_ft() const { return m_log_ft; }
00813 
00814     private:
00815       rec_beta_mi() : rec_radiation(sel_beta_mi) {}
00816 
00817       unsigned int      m_un_forbiddenness : 4; // V16 (0=allowed, 1, ..., 9)
00818       unsigned int      m_un_unique : 1;
00819       confiv_t          m_log_ft;
00820 
00821       friend class parser;
00822   };
00823 
00824   // 11. The EC (or EC + β+) Record
00825   /** An ENSDF β+ decay and electron capture record. */
00826   struct rec_beta_pl : rec_radiation
00827   {
00828       void dump(std::ostream&) const;
00829       void sync(io::syncstream&);
00830 
00831       int  forbiddenness()           const { return m_un_forbiddenness; }
00832       bool forbiddenness_is_unique() const { return m_un_unique; }
00833 
00834       /** The β+ and EC intensity.  The unit is given in the
00835        ** normalization record. */
00836       confiv_t const& I_tot_rel() const { return m_TI; }
00837 
00838       /** The β+ intensity.  The unit is given in the normalization
00839        ** record. */
00840       confiv_t const& I_beta_pl_rel() const { return m_IX; }
00841 
00842       /** The EC intensity.  The unit is given in the normalization
00843        ** record */
00844       confiv_t const& I_EC_rel() const { return m_IE; }
00845 
00846       /** The log(<i>ft</i>) value. */
00847       confiv_t const& log_ft() const { return m_log_ft; }
00848 
00849     private:
00850       rec_beta_pl() : rec_radiation(sel_beta_pl) {}
00851 
00852       unsigned int      m_un_forbiddenness : 4; // V16
00853       unsigned int      m_un_unique : 1;
00854       confiv_t          m_log_ft;
00855       confiv_t          m_IE;
00856       confiv_t          m_TI;
00857 
00858       friend class parser;
00859   };
00860 
00861   // 12. The Alpha Record
00862   /** An ENSDF α particle decay record. */
00863   struct rec_alpha : rec_radiation
00864   {
00865       void dump(std::ostream&) const;
00866       void sync(io::syncstream&);
00867 
00868       /** The hindrance factor. */
00869       confiv_t const& hindrance_factor() const { return m_HF; }
00870 
00871       /** The α-decay intensity divided by the total α-decay
00872        ** intensity. */
00873       confiv_t const& I_alpha() const { return m_IX; }
00874 
00875     private:
00876       rec_alpha() : rec_radiation(sel_alpha) {}
00877 
00878       confiv_t m_HF;
00879 
00880       friend class parser;
00881   };
00882 
00883   // 13. The (Delayed-) Particle Record
00884   /** An ENSDF particle or delayed particle record. */
00885   struct rec_particle : rec_radiation
00886   {
00887       void dump(std::ostream&) const;
00888       void sync(io::syncstream&);
00889 
00890       /** True if this is a delayed particle record. */
00891       bool is_delayed() const { return m_delayed_p; }
00892 
00893       /** The kind of particle emitted in the decay (n, p, α). */
00894       particle_kind_t particle_kind() const { return m_particle; }
00895 
00896       /** Intensity of the (delayed) particle decay divided by the
00897        ** total (delayed) particle intensity. */
00898       confiv_t const& I_part() const { return m_IX; }
00899 
00900       /** Energy of the level in the intermediate nucleus if delayed
00901        ** particle decay.  This nucleus is (N+2, Z+2) for α, (N+1, Z)
00902        ** for n and (N, Z+1) for p decay. */
00903       confiv_t E_imedi() const
00904       {
00905           if (m_EI_given) {
00906               confiv_t r = confiv_t(m_EI, confiv_t::unknown);
00907               r.set_origin(origin_experiment);
00908               if (m_EI_given != 2)
00909                   r.be_uncertain();
00910               return r;
00911           }
00912           else
00913               return confiv_t();
00914       }
00915 
00916       /** The width (of the initial energy level) of the
00917        ** transition. */
00918       confiv_t const& Gamma_trans() const { return m_T; }
00919 
00920       /** The transfer of angular momentum in the reaction. */
00921       ang_mom_xfer_set const& ang_mom_xfer() const { return m_L; }
00922 
00923       /** Is placement is confirmed by coincidence?  Returned values
00924        ** are \c fuzzy_false, \c fuzzy_probable and \c fuzzy_true. */
00925       fuzzy_bool_t has_coincidence() const { return fuzzy_bool_t(m_coin); }
00926 
00927     private:
00928       rec_particle() : rec_radiation(sel_particle) {}
00929 
00930       particle_kind_t m_particle;
00931       double m_EI;
00932       confiv_t m_T;  // width of the transition (energy)
00933       ang_mom_xfer_set m_L;
00934       unsigned int m_coin : 3;
00935       unsigned int m_delayed_p : 1;  // 0 for prompt, 1 for delayed
00936       unsigned int m_EI_given : 2;   // 0 = no, 1 = uncertain, 2 = yes
00937 
00938       friend class parser;
00939   };
00940 
00941   // 14. The Gamma Record
00942   /** An ENSDF γ emission record. */
00943   struct rec_gamma : rec_radiation
00944   {
00945       void dump(std::ostream&) const;
00946       void sync(io::syncstream&);
00947 
00948       /** The multipolarity of the transition. */
00949       multipolarity_t const& multipolarity() const { return m_M; }
00950 
00951       /** The mixing ratio.  The returned value may have indefinite
00952        ** sign, check it with confiv_t::is_signless(). */
00953       confiv_t const& r_mix() const { return m_MR; }
00954 
00955       /** Relative γ-intensity in units defined by the normalization
00956        ** record. */
00957       confiv_t const& I_gamma_rel() const { return m_IX; }
00958 
00959       /** The total conversion coefficient. */
00960       confiv_t const& alpha_tot() const { return m_CC; }
00961 
00962       /** Relation transition intensity in units defined by the
00963        ** normalization record. */
00964       confiv_t const& I_trans_rel() const { return m_TI; }
00965 
00966       /** Is placement is confirmed by coincidence?  Returned values
00967        ** are \c fuzzy_false, \c fuzzy_probable and \c fuzzy_true. */
00968       fuzzy_bool_t has_coincidence() const { return fuzzy_bool_t(m_coin); }
00969 
00970     private:
00971       rec_gamma() : rec_radiation(sel_gamma) {}
00972       multipolarity_t m_M;
00973       confiv_t m_MR;
00974       confiv_t m_CC;
00975       confiv_t m_TI;
00976       unsigned int m_coin : 3;
00977 
00978       friend class parser;
00979   };
00980 
00981   // 10-14. Cont.
00982   inline rec_beta_mi*
00983   rec_radiation::to_beta_mi()
00984   {
00985       return is_beta_mi()? static_cast<rec_beta_mi*>(this) : 0;
00986   }
00987   inline rec_beta_pl*
00988   rec_radiation::to_beta_pl()
00989   {
00990       return is_beta_pl()? static_cast<rec_beta_pl*>(this) : 0;
00991   }
00992   inline rec_alpha*
00993   rec_radiation::to_alpha()
00994   {
00995       return is_alpha()? static_cast<rec_alpha*>(this) : 0;
00996   }
00997   inline rec_particle*
00998   rec_radiation::to_particle()
00999   {
01000       return is_particle()? static_cast<rec_particle*>(this) : 0;
01001   }
01002   inline rec_gamma*
01003   rec_radiation::to_gamma()
01004   {
01005       return is_gamma()? static_cast<rec_gamma*>(this) : 0;
01006   }
01007   inline rec_beta_mi const*
01008   rec_radiation::to_beta_mi() const
01009   {
01010       return is_beta_mi()? static_cast<rec_beta_mi const*>(this) : 0;
01011   }
01012   inline rec_beta_pl const*
01013   rec_radiation::to_beta_pl() const
01014   {
01015       return is_beta_pl()? static_cast<rec_beta_pl const*>(this) : 0;
01016   }
01017   inline rec_alpha const*
01018   rec_radiation::to_alpha() const
01019   {
01020       return is_alpha()? static_cast<rec_alpha const*>(this) : 0;
01021   }
01022   inline rec_particle const*
01023   rec_radiation::to_particle() const
01024   {
01025       return is_particle()? static_cast<rec_particle const*>(this) : 0;
01026   }
01027   inline rec_gamma const*
01028   rec_radiation::to_gamma() const
01029   {
01030       return is_gamma()? static_cast<rec_gamma const*>(this) : 0;
01031   }
01032 
01033 
01034   // 15. The Reference Record
01035   /** An ENSDF reference record. */
01036   struct rec_ref
01037   {
01038       void dump(std::ostream&) const;
01039       void sync(io::syncstream&);
01040 
01041     private:
01042       // 1-3 MASS
01043       citation_t m_keynum;
01044       std::string m_reference;
01045   };
01046 
01047 
01048   /** \class decay_info ens.h more/phys/ens.h
01049    **
01050    ** Common information to all decays in a dataset.  This includes
01051    ** the parent, normalization and production normalization
01052    ** records. */
01053   struct decay_info : gen::linked
01054   {
01055       decay_info()
01056           : m_parent(0),
01057             m_norm(0),
01058             m_pnorm(0) {}
01059 
01060       ~decay_info();
01061 
01062       /** Return the parent record or 0 if none. */
01063       rec_parent const* parent() const { return m_parent; }
01064       /** Retrun the normalization record, or 0 if none. */
01065       rec_norm const* norm() const { return m_norm; }
01066       /** Return the production normalization record, or 0 if none. */
01067       rec_pnorm const* pnorm() const { return m_pnorm; }
01068 
01069     private:
01070       unsigned int      m_index;
01071       rec_parent*       m_parent;
01072       rec_norm*         m_norm;
01073       rec_pnorm*        m_pnorm;
01074 
01075       friend class dataset;
01076       friend class parser;
01077   };
01078 
01079   /** An ENSDF data set.  Use \c ens::nucleus to obtain the datasets
01080    ** for a given nucleus. */
01081   struct dataset : gen::linked
01082   {
01083       typedef gen::link<rec_history>::const_iterator    history_iterator;
01084       typedef gen::link<rec_xref>::const_iterator       xref_iterator;
01085       typedef gen::link<rec_comment>::const_iterator    comment_iterator;
01086       typedef gen::link<rec_radiation>::const_iterator  radiation_iterator;
01087       typedef gen::link<rec_level>::const_iterator      level_iterator;
01088       typedef gen::link<decay_info>::const_iterator     decay_info_iterator;
01089 
01090       dataset() : m_qvalue(0), m_relabel_intset(0) {}
01091       ~dataset();
01092 
01093       void dump(std::ostream&) const;
01094       void sync(io::syncstream&);
01095 
01096       rec_ident const*  ident() const { return &m_ident; }
01097       rec_qvalue const* qvalue() const { return m_qvalue; }
01098 
01099       bool history_range_empty() const { return m_history.empty(); }
01100       history_iterator  history_begin() const { return m_history.begin(); }
01101       history_iterator  history_end() const { return m_history.end(); }
01102       bool xref_range_empty() const { return m_xref.empty(); }
01103       xref_iterator     xref_begin() const { return m_xref.begin(); }
01104       xref_iterator     xref_end() const { return m_xref.end(); }
01105       bool comment_range_empty() const { return m_comments.empty(); }
01106       comment_iterator  comment_begin() const { return m_comments.begin(); }
01107       comment_iterator  comment_end() const { return m_comments.end(); }
01108       bool decay_info_range_empty() const { return m_pnp.empty(); }
01109       decay_info_iterator decay_info_begin() const { return m_pnp.begin(); }
01110       decay_info_iterator decay_info_end() const { return m_pnp.end(); }
01111 
01112       bool unplaced_radiation_range_empty() const
01113       { return m_unpl_rads.empty(); }
01114       radiation_iterator unplaced_radiation_begin() const
01115       { return m_unpl_rads.begin(); }
01116       radiation_iterator unplaced_radiation_end() const
01117       { return m_unpl_rads.end(); }
01118 
01119       bool level_range_empty() const { return m_levels.empty(); }
01120       level_iterator    level_begin() const { return m_levels.begin(); }
01121       level_iterator    level_end() const { return m_levels.end(); }
01122 
01123     private:
01124       decay_info* find_pnp(unsigned index);
01125       decay_info* find_or_insert_pnp(unsigned index);
01126 
01127       rec_ident                         m_ident;
01128       gen::link<rec_history>            m_history;
01129       gen::link<rec_xref>               m_xref;
01130       gen::link<rec_comment>            m_comments;
01131       rec_qvalue*                       m_qvalue;
01132       gen::link<decay_info>             m_pnp;
01133       gen::link<rec_radiation>          m_unpl_rads;
01134       gen::link<rec_level>              m_levels;
01135 
01136       symbol_intset_t                   m_relabel_intset;
01137       std::map<symbol_t, std::string>   m_relabel_map;
01138 
01139       friend class parser;
01140   };
01141 
01142   /** \class nucleus ens.h more/phys/ens.h
01143    **
01144    ** A nucleus discriptor with access to all the datasets on the
01145    ** nucleus. */
01146   struct nucleus : phys::nucleus
01147   {
01148     private:
01149       struct dataset_container : gen::link<dataset>
01150       {
01151           dataset_container() : m_ic(0) {}
01152           unsigned int m_ic;
01153       };
01154 
01155     public:
01156       typedef dataset_container::const_iterator dataset_const_iterator;
01157       typedef dataset_container::const_iterator dataset_iterator;
01158       typedef dataset_container::const_reverse_iterator
01159               dataset_const_reverse_iterator;
01160       typedef dataset_container::const_reverse_iterator
01161               dataset_reverse_iterator;
01162 
01163       nucleus() : m_datasets(0) {}
01164 
01165       nucleus(int N, int Z)
01166           : phys::nucleus(N, Z), m_datasets(0)
01167       {
01168           init();
01169       }
01170 
01171       nucleus(nucleus const& nucl)
01172           : phys::nucleus(nucl), m_datasets(nucl.m_datasets)
01173       {
01174           if (m_datasets)
01175               ++m_datasets->m_ic;
01176       }
01177 
01178       nucleus(phys::nucleus const& nucl)
01179           : phys::nucleus(nucl), m_datasets(0)
01180       {
01181           init();
01182       }
01183 
01184       ~nucleus();
01185 
01186       nucleus&
01187       operator=(nucleus const& nucl)
01188       {
01189           this->~nucleus();
01190           new(this) nucleus(nucl);
01191           return *this;
01192       }
01193 
01194       nucleus&
01195       operator=(phys::nucleus const& nucl)
01196       {
01197           this->~nucleus();
01198           new(this) nucleus(nucl);
01199           return *this;
01200       }
01201 
01202       bool has_dataset() const { chk(); return !m_datasets->empty(); }
01203 
01204       dataset_iterator dataset_begin() { chk(); return m_datasets->begin(); }
01205       dataset_iterator dataset_end()   { chk(); return m_datasets->end(); }
01206       dataset_reverse_iterator dataset_rbegin()
01207       { chk(); return m_datasets->rbegin(); }
01208       dataset_reverse_iterator dataset_rend()
01209       { chk(); return m_datasets->rend(); }
01210 
01211       dataset_const_iterator
01212       dataset_begin() const
01213       {
01214           chk();
01215           return m_datasets->begin();
01216       }
01217 
01218       dataset_const_iterator
01219       dataset_end() const
01220       {
01221           chk();
01222           return m_datasets->end();
01223       }
01224 
01225       /** Returns a pointer to the Q-Value Record, or 0 if none. */
01226       rec_qvalue const* qvalue() const;
01227 
01228       void dump(std::ostream&) const;
01229 
01230       static void set_clog(std::ostream& os) { s_clog = &os; }
01231       static std::ostream& clog() { return *s_clog; }
01232 
01233     private:
01234       void chk() const
01235       {
01236           if (!m_datasets)
01237               throw std::logic_error("phys::ens::nucleus: "
01238                                      "Tried to access null-nucleus");
01239       }
01240 
01241       void init();
01242       dataset_container* m_datasets;
01243 
01244       static void clear_cache();
01245       static int const s_N_max = 170;
01246       static int const s_Z_max = 120;  // 170*120*12 = 244800
01247       static diag::auto_ptr<dataset_container> s_cache[s_N_max*s_Z_max];
01248       static int s_n_in_use;  // cached and in use
01249       static int s_n_unused;  // cached and not in use
01250       static std::ostream* s_clog;
01251 
01252       friend class parser;
01253   };
01254 
01255 
01256   //
01257   // Algorithms (from ens_algo.cc)
01258   //
01259 
01260   /** Return the pairing energy of \a nucl for isospin \a mt, using
01261    ** three experimental separation energies.  The returned value may
01262    ** be flagged as unknown if data is not available. */
01263   confiv_t four_point_pairing(nucleus const& nucl, math::pm_half mt);
01264 
01265   dataset const* adopted_levels_dataset(nucleus const& nucl);
01266 
01267   rec_level const* ground_state_level(nucleus const& nucl);
01268 
01269   /** Return the half-life of \a nucl if known. */
01270   confiv_t half_life(nucleus const& nucl);
01271 
01272 }}} // more::phys::ens
01273 
01274 #endif
01275 
01276 
01277 // Local Variables:
01278 // coding: utf-8
01279 // End:

Generated on Sat Sep 7 19:11:21 2002 for more with Doxygen 1.2.13.1. Doxygen 1.2.13.1 is written and copyright 1997-2002 by Dimitri van Heesch.