inline_hadspec_w.cc

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

Generated on Sun Nov 22 04:32:35 2009 for CHROMA by  doxygen 1.4.7