inline_mesonspec_w.cc

Go to the documentation of this file.
00001 // $Id: inline_mesonspec_w.cc,v 3.16 2007/10/13 20:46:29 edwards Exp $
00002 /*! \file
00003  * \brief Inline construction of meson spectrum
00004  *
00005  * Meson spectrum calculations
00006  */
00007 
00008 #include "handle.h"
00009 #include "meas/inline/hadron/inline_mesonspec_w.h"
00010 #include "meas/inline/abs_inline_measurement_factory.h"
00011 #include "meas/glue/mesplq.h"
00012 #include "util/ft/sftmom.h"
00013 #include "util/info/proginfo.h"
00014 #include "io/param_io.h"
00015 #include "io/qprop_io.h"
00016 #include "meas/inline/make_xml_file.h"
00017 #include "meas/inline/io/named_objmap.h"
00018 
00019 #include "meas/hadron/spin_insertion_factory.h"
00020 #include "meas/hadron/spin_insertion_aggregate.h"
00021 
00022 namespace Chroma 
00023 { 
00024   namespace InlineMesonSpecEnv 
00025   { 
00026     namespace
00027     {
00028       AbsInlineMeasurement* createMeasurement(XMLReader& xml_in, 
00029                                               const std::string& path) 
00030       {
00031         return new InlineMesonSpec(InlineMesonSpecParams(xml_in, path));
00032       }
00033 
00034       //! Local registration flag
00035       bool registered = false;
00036     }
00037 
00038     const std::string name = "MESON_SPECTRUM";
00039 
00040     //! Register all the factories
00041     bool registerAll() 
00042     {
00043       bool success = true; 
00044       if (! registered)
00045       {
00046         success &= SpinInsertionEnv::registerAll();
00047         success &= TheInlineMeasurementFactory::Instance().registerObject(name, createMeasurement);
00048         registered = true;
00049       }
00050       return success;
00051     }
00052   }
00053 
00054 
00055 
00056   //! Reader for parameters
00057   void read(XMLReader& xml, const string& path, 
00058             InlineMesonSpecParams::Param_t& param)
00059   {
00060     XMLReader paramtop(xml, path);
00061 
00062     int version;
00063     read(paramtop, "version", version);
00064 
00065     switch (version) 
00066     {
00067     case 1:
00068       break;
00069 
00070     default:
00071       QDPIO::cerr << "Input parameter version " << version << " unsupported." << endl;
00072       QDP_abort(1);
00073     }
00074 
00075     read(paramtop, "mom2_max", param.mom2_max);
00076     read(paramtop, "avg_equiv_mom", param.avg_equiv_mom);
00077   }
00078 
00079 
00080   //! Writer for parameters
00081   void write(XMLWriter& xml, const string& path, 
00082              const InlineMesonSpecParams::Param_t& param)
00083   {
00084     push(xml, path);
00085 
00086     int version = 1;
00087     write(xml, "version", version);
00088 
00089     write(xml, "mom2_max", param.mom2_max);
00090     write(xml, "avg_equiv_mom", param.avg_equiv_mom);
00091 
00092     pop(xml);
00093   }
00094 
00095 
00096   //! Propagator input
00097   void read(XMLReader& xml, const string& path, 
00098             InlineMesonSpecParams::NamedObject_t::Correlators_t::CorrelatorTerms_t& input)
00099   {
00100     XMLReader inputtop(xml, path);
00101 
00102     read(inputtop, "first_id", input.first_id);
00103     read(inputtop, "second_id", input.second_id);
00104     read(inputtop, "factor", input.factor);
00105 
00106     input.source_spin_insertion = readXMLGroup(inputtop, "SourceSpinInsertion", "SpinInsertionType");
00107     input.sink_spin_insertion   = readXMLGroup(inputtop, "SinkSpinInsertion", "SpinInsertionType");
00108   }
00109 
00110   //! Propagator output
00111   void write(XMLWriter& xml, const string& path, 
00112              const InlineMesonSpecParams::NamedObject_t::Correlators_t::CorrelatorTerms_t& input)
00113   {
00114     push(xml, path);
00115 
00116     write(xml, "first_id", input.first_id);
00117     write(xml, "second_id", input.second_id);
00118     xml << input.source_spin_insertion.xml;
00119     xml << input.sink_spin_insertion.xml;
00120     write(xml, "factor", input.factor);
00121 
00122     pop(xml);
00123   }
00124 
00125 
00126   //! Propagator input
00127   void read(XMLReader& xml, const string& path, 
00128             InlineMesonSpecParams::NamedObject_t::Correlators_t& input)
00129   {
00130     XMLReader inputtop(xml, path);
00131 
00132     read(inputtop, "source_particle", input.source_particle);
00133     read(inputtop, "source_wavetype", input.source_wavetype);
00134     read(inputtop, "sink_particle", input.sink_particle);
00135     read(inputtop, "sink_wavetype", input.sink_wavetype);
00136     read(inputtop, "correlator_terms", input.correlator_terms);
00137   }
00138 
00139   //! Propagator output
00140   void write(XMLWriter& xml, const string& path, 
00141              const InlineMesonSpecParams::NamedObject_t::Correlators_t& input)
00142   {
00143     push(xml, path);
00144 
00145     write(xml, "source_particle", input.source_particle);
00146     write(xml, "source_wavetype", input.source_wavetype);
00147     write(xml, "sink_particle", input.sink_particle);
00148     write(xml, "sink_wavetype", input.sink_wavetype);
00149     write(xml, "correlator_terms", input.correlator_terms);
00150 
00151     pop(xml);
00152   }
00153 
00154 
00155   //! Propagator input
00156   void read(XMLReader& xml, const string& path, 
00157             InlineMesonSpecParams::NamedObject_t& input)
00158   {
00159     XMLReader inputtop(xml, path);
00160 
00161     read(inputtop, "gauge_id", input.gauge_id);
00162     read(inputtop, "correlators", input.correlators);
00163   }
00164 
00165   //! Propagator output
00166   void write(XMLWriter& xml, const string& path, 
00167              const InlineMesonSpecParams::NamedObject_t& input)
00168   {
00169     push(xml, path);
00170 
00171     write(xml, "gauge_id", input.gauge_id);
00172     write(xml, "correlators", input.correlators);
00173 
00174     pop(xml);
00175   }
00176 
00177 
00178   // Param stuff
00179   InlineMesonSpecParams::InlineMesonSpecParams() { frequency = 0; }
00180 
00181   InlineMesonSpecParams::InlineMesonSpecParams(XMLReader& xml_in, const std::string& path) 
00182   {
00183     try 
00184     {
00185       XMLReader paramtop(xml_in, path);
00186 
00187       if (paramtop.count("Frequency") == 1)
00188         read(paramtop, "Frequency", frequency);
00189       else
00190         frequency = 1;
00191 
00192       // Parameters for source construction
00193       read(paramtop, "Param", param);
00194 
00195       // Read in the output propagator/source configuration info
00196       read(paramtop, "NamedObject", named_obj);
00197 
00198       // Possible alternate XML file pattern
00199       if (paramtop.count("xml_file") != 0) 
00200       {
00201         read(paramtop, "xml_file", xml_file);
00202       }
00203     }
00204     catch(const std::string& e) 
00205     {
00206       QDPIO::cerr << __func__ << ": Caught Exception reading XML: " << e << endl;
00207       QDP_abort(1);
00208     }
00209   }
00210 
00211 
00212   // Writer
00213   void
00214   InlineMesonSpecParams::write(XMLWriter& xml_out, const std::string& path) 
00215   {
00216     push(xml_out, path);
00217     
00218     Chroma::write(xml_out, "Param", param);
00219     Chroma::write(xml_out, "NamedObject", named_obj);
00220     QDP::write(xml_out, "xml_file", xml_file);
00221 
00222     pop(xml_out);
00223   }
00224 
00225 
00226   // Anonymous namespace
00227   namespace 
00228   {
00229     //! Useful structure holding sink props
00230     struct SinkPropContainer_t
00231     {
00232       ForwardProp_t prop_header;
00233       string quark_propagator_id;
00234       Real Mass;
00235     
00236       // Now loop over the various fermion masses
00237       string source_type;
00238       string source_disp_type;
00239       string sink_type;
00240       string sink_disp_type;
00241     };
00242 
00243 
00244     //! Useful structure holding sink props
00245     struct AllCorrelatorTerms_t
00246     {
00247       SinkPropContainer_t  sink_prop_1;
00248       SinkPropContainer_t  sink_prop_2;
00249     };
00250 
00251 
00252     //! Read a sink prop
00253     void readSinkProp(SinkPropContainer_t& s, const std::string& id)
00254     {
00255       try
00256       {
00257         // Try a cast to see if it succeeds
00258         const LatticePropagator& foo = 
00259           TheNamedObjMap::Instance().getData<LatticePropagator>(id);
00260 
00261         // Snarf the data into a copy
00262         s.quark_propagator_id = id;
00263         
00264         // Snarf the prop info. This is will throw if the prop_id is not there
00265         XMLReader prop_file_xml, prop_record_xml;
00266         TheNamedObjMap::Instance().get(id).getFileXML(prop_file_xml);
00267         TheNamedObjMap::Instance().get(id).getRecordXML(prop_record_xml);
00268    
00269         // Try to invert this record XML into a ChromaProp struct
00270         // Also pull out the id of this source
00271         {
00272           read(prop_record_xml, "/SinkSmear", s.prop_header);
00273           
00274           read(prop_record_xml, "/SinkSmear/PropSource/Source/SourceType", s.source_type);
00275           read(prop_record_xml, "/SinkSmear/PropSource/Source/Displacement/DisplacementType", 
00276                s.source_disp_type);
00277 
00278           read(prop_record_xml, "/SinkSmear/PropSink/Sink/SinkType", s.sink_type);
00279           read(prop_record_xml, "/SinkSmear/PropSink/Sink/Displacement/DisplacementType", 
00280                s.sink_disp_type);
00281         }
00282       }
00283       catch( std::bad_cast ) 
00284       {
00285         QDPIO::cerr << InlineMesonSpecEnv::name << ": caught dynamic cast error" 
00286                     << endl;
00287         QDP_abort(1);
00288       }
00289       catch (const string& e) 
00290       {
00291         QDPIO::cerr << InlineMesonSpecEnv::name << ": error message: " << e 
00292                     << endl;
00293         QDP_abort(1);
00294       }
00295 
00296 
00297       // Derived from input prop
00298       // Hunt around to find the mass
00299       // NOTE: this may be problematic in the future if actions are used with no
00300       // clear def. of a Mass
00301       QDPIO::cout << "Try action and mass" << endl;
00302       s.Mass = getMass(s.prop_header.prop_header.fermact);
00303     
00304       QDPIO::cout << "FermAct = " << s.prop_header.prop_header.fermact.id << endl;
00305       QDPIO::cout << "Mass = " << s.Mass << endl;
00306     }
00307 
00308 
00309     //! Read all sinks
00310     void readAllSinks(multi1d<AllCorrelatorTerms_t>& s, 
00311                       const multi1d<InlineMesonSpecParams::NamedObject_t::Correlators_t::CorrelatorTerms_t>& correlator_terms)
00312     {
00313       s.resize(correlator_terms.size());
00314 
00315       for(int i=0; i < correlator_terms.size(); ++i)
00316       {
00317         QDPIO::cout << "Attempt to parse forward propagator = " << correlator_terms[i].first_id << endl;
00318         readSinkProp(s[i].sink_prop_1, correlator_terms[i].first_id);
00319         QDPIO::cout << "Forward propagator successfully parsed" << endl;
00320 
00321         QDPIO::cout << "Attempt to parse forward propagator = " << correlator_terms[i].second_id << endl;
00322         readSinkProp(s[i].sink_prop_2, correlator_terms[i].second_id);
00323         QDPIO::cout << "Forward propagator successfully parsed" << endl;
00324       }
00325     }
00326 
00327   } // namespace anonymous
00328 
00329 
00330 
00331   // Function call
00332   void 
00333   InlineMesonSpec::operator()(unsigned long update_no,
00334                               XMLWriter& xml_out) 
00335   {
00336     // If xml file not empty, then use alternate
00337     if (params.xml_file != "")
00338     {
00339       string xml_file = makeXMLFileName(params.xml_file, update_no);
00340 
00341       push(xml_out, "MesonSpectrum");
00342       write(xml_out, "update_no", update_no);
00343       write(xml_out, "xml_file", xml_file);
00344       pop(xml_out);
00345 
00346       XMLFileWriter xml(xml_file);
00347       func(update_no, xml);
00348     }
00349     else
00350     {
00351       func(update_no, xml_out);
00352     }
00353   }
00354 
00355 
00356 
00357   // Real work done here
00358   void 
00359   InlineMesonSpec::func(unsigned long update_no,
00360                         XMLWriter& xml_out) 
00361   {
00362     START_CODE();
00363 
00364     QDPIO::cout << InlineMesonSpecEnv::name << ": meson spectroscopy for Wilson-like fermions" << endl;
00365 
00366     StopWatch snoop;
00367     snoop.reset();
00368     snoop.start();
00369 
00370     // Test and grab a reference to the gauge field
00371     XMLBufferWriter gauge_xml;
00372     try
00373     {
00374       TheNamedObjMap::Instance().getData< multi1d<LatticeColorMatrix> >(params.named_obj.gauge_id);
00375       TheNamedObjMap::Instance().get(params.named_obj.gauge_id).getRecordXML(gauge_xml);
00376     }
00377     catch( std::bad_cast ) 
00378     {
00379       QDPIO::cerr << InlineMesonSpecEnv::name << ": caught dynamic cast error" 
00380                   << endl;
00381       QDP_abort(1);
00382     }
00383     catch (const string& e) 
00384     {
00385       QDPIO::cerr << InlineMesonSpecEnv::name << ": map call failed: " << e 
00386                   << endl;
00387       QDP_abort(1);
00388     }
00389     const multi1d<LatticeColorMatrix>& u = 
00390       TheNamedObjMap::Instance().getData< multi1d<LatticeColorMatrix> >(params.named_obj.gauge_id);
00391 
00392     push(xml_out, "MesonSpectrum");
00393     write(xml_out, "update_no", update_no);
00394 
00395     proginfo(xml_out);    // Print out basic program info
00396 
00397     QDPIO::cout << "xml_file = " << params.xml_file << endl;
00398 
00399     // Write out the input
00400     params.write(xml_out, "Input");
00401 
00402     // Write out the config info
00403     write(xml_out, "Config_info", gauge_xml);
00404 
00405     push(xml_out, "Output_version");
00406     write(xml_out, "out_version", 3);
00407     pop(xml_out);
00408 
00409 
00410     // First calculate some gauge invariant observables just for info.
00411     MesPlq(xml_out, "Observables", u);
00412 
00413     // Keep an array of all the xml output buffers
00414     push(xml_out, "Wilson_hadron_measurements");
00415 
00416     // Now loop over the various fermion pairs
00417     for(int lpair=0; lpair < params.named_obj.correlators.size(); ++lpair)
00418     {
00419       const InlineMesonSpecParams::NamedObject_t::Correlators_t named_obj = params.named_obj.correlators[lpair];
00420 
00421       push(xml_out, "elem");
00422 
00423       write(xml_out, "source_particle", named_obj.source_particle);
00424       write(xml_out, "source_wavetype", named_obj.source_wavetype);
00425       write(xml_out, "sink_particle", named_obj.sink_particle);
00426       write(xml_out, "sink_wavetype", named_obj.sink_wavetype);
00427 
00428       multi1d<AllCorrelatorTerms_t> all_sinks;
00429       readAllSinks(all_sinks, named_obj.correlator_terms);
00430 
00431       // Derived from input prop
00432       multi1d<int> t_srce
00433                   = all_sinks[0].sink_prop_1.prop_header.source_header.getTSrce();
00434       int j_decay = all_sinks[0].sink_prop_1.prop_header.source_header.j_decay;
00435       int t0      = all_sinks[0].sink_prop_1.prop_header.source_header.t_source;
00436 
00437       // Sanity checks
00438       for(int loop=0; loop < all_sinks.size(); ++loop)
00439       {
00440         if (all_sinks[loop].sink_prop_2.prop_header.source_header.j_decay != j_decay)
00441         {
00442           QDPIO::cerr << "Error!! j_decay must be the same for all propagators " << endl;
00443           QDP_abort(1);
00444         }
00445         if (all_sinks[loop].sink_prop_2.prop_header.source_header.t_source != 
00446             all_sinks[loop].sink_prop_1.prop_header.source_header.t_source)
00447         {
00448           QDPIO::cerr << "Error!! t_source must be the same for all propagators " << endl;
00449           QDP_abort(1);
00450         }
00451       }
00452         
00453 
00454       // Initialize the slow Fourier transform phases
00455       SftMom phases(params.param.mom2_max, t_srce, params.param.avg_equiv_mom,
00456                     j_decay);
00457 
00458       // Keep a copy of the phases with NO momenta
00459       SftMom phases_nomom(0, true, j_decay);
00460 
00461       // Masses
00462       write(xml_out, "Mass_1", all_sinks[0].sink_prop_1.Mass);
00463       write(xml_out, "Mass_2", all_sinks[0].sink_prop_2.Mass);
00464       write(xml_out, "t0", t0);
00465 
00466       // Save prop input
00467       push(xml_out, "Forward_prop_headers");
00468       for(int loop=0; loop < all_sinks.size(); ++loop)
00469       {
00470         push(xml_out, "elem");
00471         write(xml_out, "First_forward_prop", all_sinks[loop].sink_prop_1.prop_header);
00472         write(xml_out, "Second_forward_prop", all_sinks[loop].sink_prop_2.prop_header);
00473         pop(xml_out);
00474       }
00475       pop(xml_out);
00476 
00477       // Sanity check - write out the norm2 of the forward prop in the j_decay direction
00478       // Use this for any possible verification
00479       push(xml_out, "Forward_prop_correlator");
00480       for(int loop=0; loop < all_sinks.size(); ++loop)
00481       {
00482         const LatticePropagator& sink_prop_1 = 
00483           TheNamedObjMap::Instance().getData<LatticePropagator>(all_sinks[loop].sink_prop_1.quark_propagator_id);
00484         const LatticePropagator& sink_prop_2 = 
00485           TheNamedObjMap::Instance().getData<LatticePropagator>(all_sinks[loop].sink_prop_2.quark_propagator_id);
00486 
00487         push(xml_out, "elem");
00488         write(xml_out, "forward_prop_corr_1", sumMulti(localNorm2(sink_prop_1), phases.getSet()));
00489         write(xml_out, "forward_prop_corr_2", sumMulti(localNorm2(sink_prop_2), phases.getSet()));
00490         pop(xml_out);
00491       }
00492       pop(xml_out);
00493 
00494 
00495       push(xml_out, "SourceSinkType");
00496       for(int loop=0; loop < all_sinks.size(); ++loop)
00497       {
00498         push(xml_out, "elem");
00499         QDPIO::cout << "Source_type_1 = " << all_sinks[loop].sink_prop_1.source_type << endl;
00500         QDPIO::cout << "Sink_type_1 = " << all_sinks[loop].sink_prop_1.sink_type << endl;
00501         QDPIO::cout << "Source_type_2 = " << all_sinks[loop].sink_prop_2.source_type << endl;
00502         QDPIO::cout << "Sink_type_2 = " << all_sinks[loop].sink_prop_2.sink_type << endl;
00503 
00504         write(xml_out, "source_type_1", all_sinks[loop].sink_prop_1.source_type);
00505         write(xml_out, "source_disp_type_1", all_sinks[loop].sink_prop_1.source_disp_type);
00506         write(xml_out, "sink_type_1", all_sinks[loop].sink_prop_1.sink_type);
00507         write(xml_out, "sink_disp_type_1", all_sinks[loop].sink_prop_1.sink_disp_type);
00508 
00509         write(xml_out, "source_type_2", all_sinks[loop].sink_prop_2.source_type);
00510         write(xml_out, "source_disp_type_2", all_sinks[loop].sink_prop_2.source_disp_type);
00511         write(xml_out, "sink_type_2", all_sinks[loop].sink_prop_2.sink_type);
00512         write(xml_out, "sink_disp_type_2", all_sinks[loop].sink_prop_2.sink_disp_type);
00513         pop(xml_out);
00514       }
00515       pop(xml_out);
00516 
00517 
00518       // Do the mesons
00519       push(xml_out, "Mesons");
00520       {
00521         // Length of lattice in decay direction
00522         int length = phases.numSubsets();
00523 
00524         // Construct the anti-quark propagator from quark_propagator[1]
00525         int G5 = Ns*Ns-1;
00526 
00527         // Construct the meson correlation function
00528         LatticeComplex corr_fn = zero;
00529 
00530         for(int loop=0; loop < all_sinks.size(); ++loop)
00531         {
00532           const LatticePropagator& sink_prop_1 = 
00533             TheNamedObjMap::Instance().getData<LatticePropagator>(all_sinks[loop].sink_prop_1.quark_propagator_id);
00534           const LatticePropagator& sink_prop_2 = 
00535             TheNamedObjMap::Instance().getData<LatticePropagator>(all_sinks[loop].sink_prop_2.quark_propagator_id);
00536 
00537           LatticePropagator prop_1, prop_2;
00538 
00539           // Factory constructions
00540           try
00541           {
00542             // Create the source spin insertion object
00543             {
00544               std::istringstream  xml_s(named_obj.correlator_terms[loop].source_spin_insertion.xml);
00545               XMLReader  inserttop(xml_s);
00546 //            const string insert_path = "/SourceSpinInsertion";
00547         
00548               Handle< SpinInsertion<LatticePropagator> > sourceSpinInsertion(
00549                 ThePropSpinInsertionFactory::Instance().createObject(
00550                   named_obj.correlator_terms[loop].source_spin_insertion.id,
00551                   inserttop,
00552                   named_obj.correlator_terms[loop].source_spin_insertion.path));
00553 
00554               prop_1 = (*sourceSpinInsertion)(sink_prop_1);
00555             }
00556 
00557             // Create the sink spin insertion object
00558             {
00559               std::istringstream  xml_s(named_obj.correlator_terms[loop].sink_spin_insertion.xml);
00560               XMLReader  inserttop(xml_s);
00561 //            const string insert_path = "/SinkSpinInsertion";
00562         
00563               Handle< SpinInsertion<LatticePropagator> > sinkSpinInsertion(
00564                 ThePropSpinInsertionFactory::Instance().createObject(
00565                   named_obj.correlator_terms[loop].sink_spin_insertion.id,
00566                   inserttop,
00567                   named_obj.correlator_terms[loop].sink_spin_insertion.path));
00568 
00569               LatticePropagator prop_tmp = Gamma(G5) * adj(sink_prop_2) * Gamma(G5);
00570 
00571               prop_2 = (*sinkSpinInsertion)(prop_tmp);
00572             }
00573           }
00574           catch(const std::string& e) 
00575           {
00576             QDPIO::cerr << InlineMesonSpecEnv::name << ": Caught Exception inserting: " 
00577                         << e << endl;
00578             QDP_abort(1);
00579           }
00580 
00581 
00582           LatticeComplex tmp = trace(prop_2 * prop_1);
00583 
00584           corr_fn += named_obj.correlator_terms[loop].factor * tmp;
00585         }
00586 
00587         multi2d<DComplex> hsum;
00588         hsum = phases.sft(corr_fn);
00589 
00590         // Loop over sink momenta
00591         XMLArrayWriter xml_sink_mom(xml_out,phases.numMom());
00592         push(xml_sink_mom, "momenta");
00593 
00594         for (int sink_mom_num=0; sink_mom_num < phases.numMom(); ++sink_mom_num) 
00595         {
00596           push(xml_sink_mom);
00597           write(xml_sink_mom, "sink_mom_num", sink_mom_num);
00598           write(xml_sink_mom, "sink_mom", phases.numToMom(sink_mom_num));
00599 
00600           multi1d<DComplex> mesprop(length);
00601           for (int t=0; t < length; ++t) 
00602           {
00603             int t_eff = (t - t0 + length) % length;
00604             mesprop[t_eff] = hsum[sink_mom_num][t];
00605           }
00606 
00607           write(xml_sink_mom, "mesprop", mesprop);
00608           pop(xml_sink_mom);
00609         
00610         } // end for(sink_mom_num)
00611  
00612         pop(xml_sink_mom);
00613       }
00614       pop(xml_out);  // Mesons
00615 
00616       pop(xml_out);  // array element
00617     }
00618     pop(xml_out);  // Wilson_spectroscopy
00619     pop(xml_out);  // mesonspec
00620 
00621     snoop.stop();
00622     QDPIO::cout << InlineMesonSpecEnv::name << ": total time = "
00623                 << snoop.getTimeInSeconds() 
00624                 << " secs" << endl;
00625 
00626     QDPIO::cout << InlineMesonSpecEnv::name << ": ran successfully" << endl;
00627 
00628     END_CODE();
00629   } 
00630 
00631 };

Generated on Mon Mar 15 04:32:49 2010 for CHROMA by  doxygen 1.4.7