inline_stoch_group_baryon_w.cc

Go to the documentation of this file.
00001 // $Id: inline_stoch_group_baryon_w.cc,v 1.28 2009/05/19 20:43:05 jbulava Exp $
00002 /*! \file
00003  * \brief Inline measurement of stochastic group baryon operator
00004  *
00005  */
00006 
00007 #include "handle.h"
00008 #include "meas/inline/hadron/inline_stoch_group_baryon_w.h"
00009 #include "meas/inline/abs_inline_measurement_factory.h"
00010 #include "meas/smear/quark_smearing_factory.h"
00011 #include "meas/smear/quark_smearing_aggregate.h"
00012 #include "meas/sources/source_smearing_aggregate.h"
00013 #include "meas/sources/source_smearing_factory.h"
00014 #include "meas/sinks/sink_smearing_aggregate.h"
00015 #include "meas/sinks/sink_smearing_factory.h"
00016 #include "meas/hadron/dilution_scheme_aggregate.h"
00017 #include "meas/hadron/dilution_scheme_factory.h"
00018 #include "meas/glue/mesplq.h"
00019 #include "meas/smear/displacement.h"
00020 #include "util/ferm/diractodr.h"
00021 #include "util/ft/sftmom.h"
00022 #include "util/info/proginfo.h"
00023 #include "meas/inline/make_xml_file.h"
00024 #include <sstream> 
00025 
00026 #include "meas/inline/io/named_objmap.h"
00027 
00028 namespace Chroma 
00029 { 
00030   /*!
00031    * \ingroup hadron
00032    *
00033    * @{
00034    */
00035   namespace InlineStochGroupBaryonEnv 
00036   { 
00037     //! Number of quarks to be used in this construction
00038     const int N_quarks = 3;
00039         
00040         
00041     //
00042     // The spin basis matrix to goto Dirac
00043     //
00044     SpinMatrix rotate_mat(adj(DiracToDRMat()));
00045 
00046     // Reader for input parameters
00047     void read(XMLReader& xml, const string& path, InlineStochGroupBaryonEnv::Params::Param_t& param)
00048     {
00049       XMLReader paramtop(xml, path);
00050 
00051                         int version;
00052                         read(paramtop, "version", version);
00053 
00054                                         multi1d< multi1d<int> > temp;
00055                         switch (version) 
00056                         {
00057                                 case 1:
00058                                         
00059                                         QDPIO::cerr << "version 1 no longer supported. " << endl;
00060                                         exit(0);
00061                                         /*
00062                                         read(paramtop, "mom2_max", param.mom2_max);
00063 
00064 
00065                                 
00066                                         param.moms.resize(1,3);
00067                                 
00068                                         param.moms[0][0] = 0;
00069                                         param.moms[0][1] = 0;
00070                                         param.moms[0][2] = 0;
00071                                         
00072                                         */
00073 
00074                                         break;
00075 
00076                                 case 2:
00077 
00078                                         read(paramtop, "moms" , temp);
00079 
00080                                         param.mom2_max = 0;
00081                                         param.moms.resize(temp.size(), temp[0].size() );
00082 
00083                                         for (int i = 0 ; i < temp.size() ; ++i) 
00084                                                 param.moms[i] = temp[i];
00085 
00086 
00087                                         break;
00088                                 
00089                                 default :
00090 
00091                                         QDPIO::cerr << "Input parameter version " << version << " unsupported." << endl;
00092                                         QDP_abort(1);
00093                         }
00094 
00095                         read(paramtop, "displacement_length", param.displacement_length);
00096 
00097                         param.quark_smearing = readXMLGroup(paramtop, "QuarkSmearing", "wvf_kind");
00098                         param.link_smearing         = readXMLGroup(paramtop, "LinkSmearing", "LinkSmearingType");
00099                         param.quark_dils             = readXMLArrayGroup(paramtop, "QuarkDilutions", "DilutionType");
00100 
00101 
00102                 }
00103 
00104 
00105                 // Writer for input parameters
00106                 void write(XMLWriter& xml, const string& path, const InlineStochGroupBaryonEnv::Params::Param_t& param)
00107                 {
00108                         push(xml, path);
00109 
00110                         int version = 1;
00111 
00112                         write(xml, "version", version);
00113                         write(xml, "mom2_max", param.mom2_max);
00114                         write(xml, "displacement_length", param.displacement_length);
00115                         xml << param.quark_smearing.xml;
00116       xml << param.link_smearing.xml;
00117 
00118       push(xml, "QuarkDilutions");
00119 
00120       for(int i=0; i < param.quark_dils.size(); ++i)
00121         xml << param.quark_dils[i].xml;
00122 
00123       pop(xml);
00124 
00125       pop(xml);
00126     }
00127 
00128 
00129     //Reader for 3-quark operator file
00130     void read(XMLReader& xml, const string& path, InlineStochGroupBaryonEnv::Params::NamedObject_t::ThreeQuarkOpsFile_t& input)
00131     {
00132       XMLReader inputtop(xml, path);
00133 
00134       read(inputtop, "ops_file", input.ops_file);
00135       read(inputtop, "id", input.id);
00136     }
00137 
00138 
00139     // Writer for 3-quark operator file
00140     void write(XMLWriter& xml, const string& path, const InlineStochGroupBaryonEnv::Params::NamedObject_t::ThreeQuarkOpsFile_t& input)
00141     {
00142       push(xml, path);
00143       write(xml, "ops_file", input.ops_file);
00144       write(xml, "id", input.id);
00145       pop(xml);
00146     }
00147 
00148 
00149     //! Read named objects 
00150     void read(XMLReader& xml, const string& path, InlineStochGroupBaryonEnv::Params::NamedObject_t& input)
00151     {
00152       XMLReader inputtop(xml, path);
00153 
00154       read(inputtop, "gauge_id", input.gauge_id);
00155       read(inputtop, "operators_file", input.operators_file);
00156       read(inputtop, "Quark_ids", input.quark_ids);
00157     }
00158 
00159     //! Write named objects
00160     void write(XMLWriter& xml, const string& path, const InlineStochGroupBaryonEnv::Params::NamedObject_t& input)
00161     {
00162       push(xml, path);
00163 
00164       write(xml, "gauge_id", input.gauge_id);
00165       write(xml, "operators_file", input.operators_file);
00166       write(xml, "Quark_ids", input.quark_ids);
00167 
00168       pop(xml);
00169     }
00170   }
00171 
00172 
00173   namespace InlineStochGroupBaryonEnv 
00174   { 
00175     // Anonymous namespace for registration
00176     namespace
00177     {
00178       AbsInlineMeasurement* createMeasurement(XMLReader& xml_in, 
00179                                               const std::string& path) 
00180       {
00181         return new InlineMeas(Params(xml_in, path));
00182       }
00183 
00184       //! Local registration flag
00185       bool registered = false;
00186     }
00187 
00188     const std::string name = "STOCH_GROUP_BARYON";
00189 
00190     //! Register all the factories
00191     bool registerAll() 
00192     {
00193       bool success = true; 
00194       if (! registered)
00195       {
00196         success &= QuarkSourceSmearingEnv::registerAll();
00197         success &= QuarkSinkSmearingEnv::registerAll();
00198         success &= DilutionSchemeEnv::registerAll();
00199         success &= TheInlineMeasurementFactory::Instance().registerObject(name, createMeasurement);
00200         registered = true;
00201       }
00202       return success;
00203     }
00204 
00205 
00206     //----------------------------------------------------------------------------
00207     // Param stuff
00208     Params::Params()
00209     { 
00210       frequency = 0; 
00211       param.mom2_max = 0;
00212     }
00213 
00214     Params::Params(XMLReader& xml_in, const std::string& path) 
00215     {
00216       try 
00217       {
00218         XMLReader paramtop(xml_in, path);
00219 
00220         if (paramtop.count("Frequency") == 1)
00221           read(paramtop, "Frequency", frequency);
00222         else
00223           frequency = 1;
00224 
00225         // Read program parameters
00226         read(paramtop, "Param", param);
00227 
00228         // Read in the output propagator/source configuration info
00229         read(paramtop, "NamedObject", named_obj);
00230 
00231         // Possible alternate XML file pattern
00232         if (paramtop.count("xml_file") != 0) 
00233         {
00234           read(paramtop, "xml_file", xml_file);
00235         }
00236       }
00237       catch(const std::string& e) 
00238       {
00239         QDPIO::cerr << __func__ << ": Caught Exception reading XML: " << e << endl;
00240         QDP_abort(1);
00241       }
00242     }
00243 
00244 
00245     void
00246     Params::writeXML(XMLWriter& xml_out, const std::string& path) 
00247     {
00248       push(xml_out, path);
00249     
00250       // Parameters for source construction
00251       write(xml_out, "Param", param);
00252 
00253       // Write out the output propagator/source configuration info
00254       write(xml_out, "NamedObject", named_obj);
00255 
00256       pop(xml_out);
00257     }
00258 
00259 
00260 
00261     //--------------------------------------------------------------
00262     //! 3-quark operator structure
00263     struct ThreeQuarkOps_t
00264     {
00265       struct ThreeQuarkOp_t
00266       {
00267         struct QuarkInfo_t
00268         {
00269           int  displacement;    /*!< Orig plus/minus 1-based directional displacements */
00270           int  spin;            /*!< 1-based spin index */
00271         };
00272 
00273         multi1d<QuarkInfo_t>  quark;    /*!< Displacement and spin for each quark */
00274         std::string name;               /*!< Name of the 3-quark operator */
00275       };
00276         
00277       multi1d<ThreeQuarkOp_t> ops; /*!< 3-quark ops within a file */
00278     };
00279 
00280     //! Write quark 
00281     void write(XMLWriter& xml, const string& path, 
00282                const ThreeQuarkOps_t::ThreeQuarkOp_t::QuarkInfo_t& input)
00283     {
00284       push(xml, path);
00285 
00286       write(xml, "Displacement", input.displacement);
00287       write(xml, "Spin", input.spin);
00288 
00289       pop(xml);
00290     }
00291 
00292     //! Write three quark op 
00293     void write(XMLWriter& xml, const string& path, 
00294                const ThreeQuarkOps_t::ThreeQuarkOp_t& input)
00295     {
00296       push(xml, path);
00297 
00298       write(xml, "Quarks", input.quark);
00299       write(xml, "Name", input.name);
00300 
00301       pop(xml);
00302     }
00303         
00304 
00305 
00306     //---------------------------------------------------------------------------
00307 
00308 
00309     //! The key for smeared quarks 
00310     struct KeySmearedQuark_t
00311     {
00312       int  t0;              /*!< Time of source */
00313       int dil;              /*!< dilution component per timeslice */
00314 
00315     };
00316 
00317 
00318     //! Support for the keys of smeared quarks 
00319     bool operator<(const KeySmearedQuark_t& a, const KeySmearedQuark_t& b)
00320     {
00321       multi1d<int> lga(2);
00322       lga[0] = a.t0;
00323       lga[1] = a.dil;
00324 
00325       multi1d<int> lgb(2);
00326       lgb[0] = b.t0;
00327       lgb[1] = b.dil;
00328 
00329       return (lga < lgb);
00330     }
00331 
00332 
00333     struct SmearedQuark_t
00334     {
00335       LatticeFermion quark;
00336     };
00337 
00338     //----------------------------------------------------------------------------
00339     //! The key for smeared and displaced color vectors
00340     struct KeySmearedDispColorVector_t
00341     {
00342       int  t0;              /*!< Time of source */
00343       int dil;              /*!< dilution component per timeslice */
00344 
00345       int  displacement;    /*!< Orig plus/minus 1-based directional displacements */
00346       int  spin;            /*!< 1-based spin index */
00347     };
00348 
00349 
00350     //! Support for the keys of smeared and displaced color vectors
00351     bool operator<(const KeySmearedDispColorVector_t& a, const KeySmearedDispColorVector_t& b)
00352     {
00353       multi1d<int> lga(4);
00354       lga[0] = a.displacement;
00355       lga[1] = a.spin;
00356       lga[2] = a.t0;
00357       lga[3] = a.dil;
00358 
00359       multi1d<int> lgb(4);
00360       lgb[0] = b.displacement;
00361       lgb[1] = b.spin;
00362       lgb[2] = b.t0;
00363       lgb[3] = b.dil;
00364 
00365       return (lga < lgb);
00366     }
00367 
00368 
00369     //! The value of the map
00370     struct SmearedDispColorVector_t
00371     {
00372       multi1d<LatticeComplex> vec;
00373     };
00374 
00375 
00376     //----------------------------------------------------------------------------
00377     //! The smeared and displaced objects
00378     class SmearedDispObjects
00379     {
00380     public:
00381       //! Constructor from smeared map 
00382       SmearedDispObjects(int disp_length,
00383                          multi1d< Handle< DilutionScheme<LatticeFermion> > > dil_quarks,        
00384                          Handle< QuarkSmearing<LatticeFermion> > qsmr,
00385                          const multi1d<LatticeColorMatrix> & u_smr) :
00386         displacement_length(disp_length),diluted_quarks(dil_quarks),
00387         quarkSmearing(qsmr), u(u_smr)
00388         {
00389           smeared_src_maps.resize(N_quarks);
00390           smeared_soln_maps.resize(N_quarks);
00391                         
00392           disp_src_maps.resize(N_quarks);
00393           disp_soln_maps.resize(N_quarks);
00394                                 
00395         }
00396 
00397       //! Destructor
00398       ~SmearedDispObjects() {}
00399 
00400       //! Accessor
00401       virtual multi1d<LatticeComplex> getDispSource(int quark_num,                                                 
00402                                                     const KeySmearedDispColorVector_t& key);
00403 
00404       //! Accessor
00405       virtual multi1d<LatticeComplex> getDispSolution(int quark_num,  
00406                                                       const KeySmearedDispColorVector_t& key);
00407 
00408     protected:
00409       
00410       //! Displace an object
00411       virtual const multi1d<LatticeComplex>&    displaceObject(
00412         map<KeySmearedDispColorVector_t, SmearedDispColorVector_t>& disp_quark_map,
00413         const KeySmearedDispColorVector_t& key,
00414         const LatticeFermion& smrd_q);
00415                         
00416       //! Smear sources and solutions
00417       virtual const LatticeFermion&
00418       smearSource(int qnum , const KeySmearedQuark_t & key);
00419                                          
00420       virtual const LatticeFermion&
00421       smearSolution(int qnum , const KeySmearedQuark_t & key);
00422 
00423 
00424     private:
00425      
00426       multi1d< Handle< DilutionScheme<LatticeFermion> > > diluted_quarks;       
00427                         
00428       Handle < QuarkSmearing<LatticeFermion> > quarkSmearing;
00429 
00430                 
00431       //!Gauge field 
00432       const multi1d<LatticeColorMatrix> & u;
00433                         
00434       //! Displacement length
00435       int displacement_length;
00436 
00437                         
00438       //! Maps of smeared color vectors 
00439       multi1d< map<KeySmearedQuark_t, SmearedQuark_t> > smeared_src_maps;
00440       multi1d< map<KeySmearedQuark_t, SmearedQuark_t> > smeared_soln_maps;
00441 
00442       
00443       //!Maps of smeared displaced color vectors 
00444       multi1d< map<KeySmearedDispColorVector_t, SmearedDispColorVector_t> > disp_src_maps;
00445       multi1d< map<KeySmearedDispColorVector_t, SmearedDispColorVector_t> > disp_soln_maps;
00446     };
00447 
00448         
00449     const LatticeFermion&
00450     SmearedDispObjects::smearSource(int qnum , 
00451                                     const KeySmearedQuark_t & key)
00452     {
00453 
00454       map<KeySmearedQuark_t, SmearedQuark_t> & qmap = smeared_src_maps[qnum];
00455 
00456       //If entry is not in map create it
00457       if ( qmap.find(key) == qmap.end() )
00458       {
00459 
00460         // Insert an empty entry and then modify it. This saves on
00461         // copying the data around
00462         {
00463           SmearedQuark_t smrd_empty;
00464           qmap.insert(std::make_pair(key, smrd_empty));
00465 
00466           // Sanity check - the entry better be there
00467           if ( qmap.find(key) == qmap.end() )
00468           {
00469             QDPIO::cerr << __func__ 
00470                         << ": internal error - could not insert empty key in map"
00471                         << endl;
00472             QDP_abort(1);
00473           }                   
00474         }
00475 
00476         // Modify the previous empty entry
00477         SmearedQuark_t& smrd_q = qmap.find(key)->second;
00478              
00479         StopWatch snoop;
00480 
00481         snoop.reset();
00482         snoop.start();
00483         
00484         smrd_q.quark = diluted_quarks[qnum]->dilutedSource(key.t0, key.dil);
00485 
00486         (*quarkSmearing)(smrd_q.quark, u);
00487 
00488         SpinMatrix mat = rotate_mat * Gamma(8);
00489                                 
00490         smrd_q.quark = mat * smrd_q.quark;
00491         
00492               
00493         snoop.stop();
00494 
00495         QDPIO::cout << " Smeared Sources: Quark = "<< qnum <<" t0 = "
00496                     << key.t0 <<" dil = "<< key.dil << " Time = "<< snoop.getTimeInSeconds() <<" sec"<<endl;
00497 
00498         // Insert
00499         qmap.insert(std::make_pair(key, smrd_q));
00500       
00501       } // if find in map
00502 
00503       // The key now must exist in the map, so return the smeared quark field
00504 
00505       return (qmap.find(key)->second).quark ;
00506     }
00507 
00508         
00509                 
00510     const LatticeFermion&
00511     SmearedDispObjects::smearSolution(int qnum , 
00512                                       const KeySmearedQuark_t & key)
00513     {
00514 
00515       map<KeySmearedQuark_t, SmearedQuark_t> & qmap = smeared_soln_maps[qnum];
00516 
00517 
00518       //If entry is not in map create it
00519       if ( qmap.find(key) == qmap.end() )
00520       {
00521 
00522         // Insert an empty entry and then modify it. This saves on
00523         // copying the data around
00524         {
00525           SmearedQuark_t smrd_empty;
00526           qmap.insert(std::make_pair(key, smrd_empty));
00527 
00528           // Sanity check - the entry better be there
00529           if ( qmap.find(key) == qmap.end() )
00530           {
00531             QDPIO::cerr << __func__ 
00532                         << ": internal error - could not insert empty key in map"
00533                         << endl;
00534             QDP_abort(1);
00535           }                   
00536         }
00537 
00538         // Modify the previous empty entry
00539         SmearedQuark_t& smrd_q = qmap.find(key)->second;
00540              
00541         StopWatch snoop;
00542         snoop.reset();
00543         snoop.start();
00544         
00545         smrd_q.quark = diluted_quarks[qnum]->dilutedSolution(key.t0, key.dil);
00546 
00547         (*quarkSmearing)(smrd_q.quark, u);
00548 
00549         smrd_q.quark = rotate_mat * smrd_q.quark;
00550         
00551         snoop.stop();
00552 
00553         QDPIO::cout << " Smeared Sinks: Quark = "<< qnum <<" t0 = "
00554                     << key.t0 <<" dil = "<< key.dil << " Time = "<< snoop.getTimeInSeconds() <<" sec"<<endl;
00555         
00556         // Insert
00557         qmap.insert(std::make_pair(key, smrd_q));
00558       
00559       } // if find in map
00560 
00561       // The key now must exist in the map, so return the smeared quark field
00562 
00563       return (qmap.find(key)->second).quark ;
00564     }
00565 
00566     //! Accessor
00567     multi1d<LatticeComplex>
00568     SmearedDispObjects::getDispSource(int quark_num, 
00569                                       const KeySmearedDispColorVector_t& key)
00570     {
00571                 
00572       //Get Smeared quark 
00573       KeySmearedQuark_t smr_key;
00574       smr_key.t0 = key.t0;
00575       smr_key.dil = key.dil;
00576 
00577       const LatticeFermion& smrd_q = smearSource(quark_num, smr_key);
00578                                         
00579       multi1d<LatticeComplex> vec;
00580 
00581       //Check if any displacement is needed
00582       if (displacement_length == 0) 
00583       {
00584         vec.resize(Nc);
00585         LatticeColorVector colvec = peekSpin( smrd_q, key.spin - 1);
00586 
00587         for (int c = 0 ; c < Nc ; ++c)
00588           vec[c] = peekColor( colvec, c);
00589 
00590       }
00591       else
00592       {
00593         vec = displaceObject( disp_src_maps[quark_num] , key , smrd_q);
00594       }
00595 
00596       return vec;
00597                 
00598     }
00599 
00600     //! Accessor
00601     multi1d<LatticeComplex>
00602     SmearedDispObjects::getDispSolution(int quark_num, 
00603                                         const KeySmearedDispColorVector_t& key)
00604     {
00605         
00606       //Get Smeared quark 
00607       KeySmearedQuark_t smr_key;
00608       smr_key.t0 = key.t0;
00609       smr_key.dil = key.dil;
00610 
00611       const LatticeFermion& smrd_q = smearSolution(quark_num, smr_key);
00612                                 
00613       multi1d<LatticeComplex> vec;
00614 
00615       //Check if any displacement is needed
00616       if (displacement_length == 0) 
00617       {
00618         vec.resize(Nc);
00619         LatticeColorVector colvec = peekSpin( smrd_q, key.spin - 1);
00620 
00621         for (int c = 0 ; c < Nc ; ++c)
00622           vec[c] = peekColor( colvec, c);
00623 
00624       }
00625       else
00626       {
00627         vec = displaceObject( disp_soln_maps[quark_num] , key , smrd_q);
00628       }
00629 
00630       return vec;
00631     }
00632 
00633 
00634     //! Accessor
00635     const multi1d<LatticeComplex> &
00636     SmearedDispObjects::displaceObject(
00637       map<KeySmearedDispColorVector_t, SmearedDispColorVector_t>& disp_quark_map,
00638       const KeySmearedDispColorVector_t& key,
00639       const LatticeFermion& smrd_q)
00640     {
00641 
00642       StopWatch snoop;
00643 
00644       // If no entry, then create a displaced version of the quark
00645       if (disp_quark_map.find(key) == disp_quark_map.end())
00646       {
00647         //            cout << __func__ 
00648         //                 << ": n=" << n
00649         //                 << " l=" << l
00650         //                 << " i=" << i 
00651         //                 << " disp=" << term.quark[i].displacement
00652         //                 << " len=" << term.quark[i].disp_len
00653         //                 << " dir=" << term.quark[i].disp_dir
00654         //                 << endl;
00655 
00656 
00657 
00658         // Insert an empty entry and then modify it. This saves on
00659         // copying the data around
00660         {
00661           SmearedDispColorVector_t disp_empty;
00662 
00663           snoop.reset();
00664           snoop.start();
00665 
00666           disp_quark_map.insert(std::make_pair(key, disp_empty));
00667 
00668           snoop.stop();
00669 
00670           QDPIO::cout<<"Inserted key in map: time = "<< snoop.getTimeInSeconds() << "secs"<<endl;
00671 
00672           // Sanity check - the entry better be there
00673           if (disp_quark_map.find(key) == disp_quark_map.end())
00674           {
00675             QDPIO::cerr << __func__ 
00676                         << ": internal error - could not insert empty key in map"
00677                         << endl;
00678             QDP_abort(1);
00679           }                   
00680         }
00681 
00682         // Modify the previous empty entry
00683         SmearedDispColorVector_t& disp_q = disp_quark_map.find(key)->second;
00684 
00685         snoop.reset();
00686         snoop.start();
00687 
00688         //Chroma uses a zero-based spin convention
00689         LatticeColorVector vec = peekSpin(smrd_q,  key.spin - 1);
00690 
00691         if (key.displacement > 0)
00692         {
00693           int disp_dir = key.displacement - 1;
00694           int disp_len = displacement_length;
00695           displacement(u, vec, disp_len, disp_dir);
00696         }
00697         else if (key.displacement < 0)
00698         {
00699           int disp_dir = -key.displacement - 1;
00700           int disp_len = -displacement_length;
00701           displacement(u, vec, disp_len, disp_dir);
00702         }
00703 
00704         snoop.stop();
00705 
00706         QDPIO::cout << "Displaced Quarks: Spin = "<<key.spin<<" Disp = "
00707                     << key.displacement <<" Time = "<<snoop.getTimeInSeconds() <<" sec"<<endl;
00708 
00709         disp_q.vec.resize(Nc);
00710 
00711         for(int i = 0 ; i < Nc ; ++i ) 
00712         {
00713           disp_q.vec[i] = peekColor(vec, i);
00714         }
00715 
00716       } // if find in map
00717 
00718       snoop.reset();
00719       snoop.start();
00720 
00721       // The key now must exist in the map, so return the vector
00722       SmearedDispColorVector_t& disp_q = disp_quark_map.find(key)->second;
00723 
00724       snoop.stop(); 
00725 
00726       //QDPIO::cout << "Retrieved entry from map : time = "<< snoop.getTimeInSeconds() << "secs "<<endl;
00727 
00728       return disp_q.vec;
00729     }
00730 
00731 
00732     //----------------------------------------------------------------------------
00733     //Support for the diquarks
00734 
00735     void makeDiquark( multi1d<LatticeComplex> & diquark, const multi1d<LatticeComplex> & q0,
00736                       const multi1d<LatticeComplex> & q1, const Subset & subset )
00737     {
00738 
00739 
00740       //The signs for the diquark are taken from
00741       //the colorContract function in qdp_primcolorvec.h
00742       diquark[0][subset] =  q0[0]*q1[1] - q0[1]*q1[0];
00743       diquark[1][subset] =  q0[1]*q1[2] - q0[2]*q1[1];
00744       diquark[2][subset] =  q0[2]*q1[0] - q0[0]*q1[2];
00745 
00746 
00747     }
00748 
00749 
00750     void makeColorSinglet (LatticeComplex & singlet, const multi1d<LatticeComplex> & diquark, 
00751                            const multi1d<LatticeComplex> & q2, const Subset & subset)
00752     {
00753 
00754       singlet[subset] = diquark[0] * q2[2];
00755       singlet[subset] += diquark[1] * q2[0];  
00756       singlet[subset] += diquark[2] * q2[1];  
00757     }
00758 
00759 
00760     //! Baryon operator
00761     struct BaryonOperator_t
00762     {
00763       //! Baryon operator time slices corresponding to location of operator source
00764       struct TimeSlices_t
00765       {
00766         //! Quark orderings within a baryon operator
00767         struct Orderings_t
00768         {
00769           //! Baryon operator dilutions
00770           struct Dilutions_t
00771           {
00772             //! Momentum projected correlator
00773             struct Mom_t
00774             {
00775               multi1d<int>       mom;         /*!< D-1 momentum of this operator */
00776               multi1d<DComplex>  op;          /*!< Momentum projected operator */
00777             };
00778 
00779             multi1d<Mom_t> mom_projs;         /*!< Holds momentum projections of the operator */
00780 
00781           };
00782 
00783           multi1d<int> perm;                  /*!< This particular permutation of quark orderings */
00784 
00785           multi3d<Dilutions_t> dilutions;     /*!< Hybrid list indices */
00786         };
00787 
00788         multi1d<Orderings_t> orderings;                         /*!< Array is over quark orderings */
00789 
00790         int t0;                                                                                                                 /*!< Actual time corresponding to this timeslice */
00791       };
00792 
00793       multi1d< multi1d<int> > perms;   /*!< Permutations of quark enumeration */
00794 
00795       GroupXML_t    smearing;          /*!< String holding quark smearing xml */
00796 
00797       Seed          seed_l;            /*!< Id of left quark */
00798       Seed          seed_m;            /*!< Id of middle quark */
00799       Seed          seed_r;            /*!< Id of right quark */
00800 
00801 
00802       GroupXML_t    dilution_l;        /*!< Dilution scheme of left quark */ 
00803       GroupXML_t    dilution_m;        /*!< Dilution scheme of middle quark */ 
00804       GroupXML_t    dilution_r;        /*!< Dilution scheme of right quark */ 
00805 
00806       std::string   id;                /*!< Tag/ID used in analysis codes */
00807 
00808       int           mom2_max;          /*!< |\vec{p}|^2 */
00809       int           decay_dir;         /*!< Direction of decay */
00810 
00811       multi1d<TimeSlices_t> time_slices; /*!< Time slices of the lattice that are used */
00812     };
00813 
00814 
00815     //----------------------------------------------------------------------------
00816     //! BaryonOperator header writer
00817     void write(XMLWriter& xml, const string& path, const BaryonOperator_t& param)
00818     {
00819       push(xml, path);
00820 
00821       int version = 1;
00822       write(xml, "version", version);
00823       write(xml, "id", param.id);
00824       write(xml, "mom2_max", param.mom2_max);
00825       write(xml, "decay_dir", param.decay_dir);
00826       write(xml, "seed_l", param.seed_l);
00827       write(xml, "seed_m", param.seed_m);
00828       write(xml, "seed_r", param.seed_r);
00829       write(xml, "perms", param.perms);
00830 
00831       push(xml, "dilution_l");
00832       xml << param.dilution_l.xml; 
00833       pop(xml);
00834 
00835       push(xml, "dilution_m");
00836       xml << param.dilution_m.xml; 
00837       pop(xml);
00838       
00839       push(xml, "dilution_r");
00840       xml << param.dilution_r.xml; 
00841       pop(xml);
00842                         
00843       xml <<  param.smearing.xml;
00844         
00845       pop(xml);
00846     }
00847 
00848 
00849 
00850     //! BaryonOperator binary writer
00851     void write(BinaryWriter& bin, const BaryonOperator_t::TimeSlices_t::Orderings_t::Dilutions_t::Mom_t& param)
00852     {
00853       write(bin, param.mom);
00854       write(bin, param.op);
00855     }
00856 
00857     //! BaryonOperator binary writer
00858     void write(BinaryWriter& bin, const BaryonOperator_t::TimeSlices_t::Orderings_t::Dilutions_t& param)
00859     {
00860       write(bin, param.mom_projs);
00861     }
00862 
00863     //! BaryonOperator binary writer
00864     void write(BinaryWriter& bin, const BaryonOperator_t::TimeSlices_t::Orderings_t& param)
00865     {
00866       write(bin, param.dilutions);
00867       write(bin, param.perm);
00868     }
00869 
00870     //! BaryonOperator binary writer
00871     void write(BinaryWriter& bin, const BaryonOperator_t::TimeSlices_t& param)
00872     {
00873       write(bin, param.orderings);
00874       write(bin, param.t0);
00875     }
00876 
00877     //! BaryonOperator binary writer
00878     void write(BinaryWriter& bin, const BaryonOperator_t& param)
00879     {
00880       write(bin, param.seed_l);
00881       write(bin, param.seed_m);
00882       write(bin, param.seed_r);
00883       write(bin, param.mom2_max);
00884       write(bin, param.decay_dir);
00885       write(bin, param.perms);
00886       write(bin, param.time_slices);
00887     }
00888 
00889 
00890     //! Read 3-quark operators file, assign correct displacement length
00891     void readOps(ThreeQuarkOps_t& oplist, 
00892                  const std::string& ops_file)
00893     {
00894       START_CODE();
00895 
00896       TextFileReader reader(ops_file);
00897 
00898       int num_ops;
00899       reader >> num_ops;
00900       oplist.ops.resize(num_ops);
00901 
00902       //Loop over ops within a file
00903       for(int n=0; n < oplist.ops.size(); ++n)
00904       {
00905         std::string name; 
00906         reader >> name;
00907         oplist.ops[n].name = name;  
00908 
00909         ThreeQuarkOps_t::ThreeQuarkOp_t& qqq = oplist.ops[n];
00910         qqq.quark.resize(N_quarks);
00911 
00912         // Read 1-based spin
00913         multi1d<int> spin(N_quarks);
00914         reader >> spin[0] >> spin[1] >> spin[2];
00915 
00916         // Read 1-based displacement
00917         multi1d<int> displacement(N_quarks);
00918         reader >> displacement[0] >> displacement[1] >> displacement[2];
00919 
00920         // Insert for each quark
00921         for(int i=0; i < qqq.quark.size(); ++i)
00922         {
00923           qqq.quark[i].spin = spin[i];
00924           qqq.quark[i].displacement = displacement[i];
00925         }
00926 
00927       } //n
00928 
00929       reader.close();
00930 
00931       END_CODE();
00932     } //void readOps
00933 
00934 
00935     //-------------------------------------------------------------------------------
00936     // Function call
00937     void 
00938     InlineMeas::operator()(unsigned long update_no,
00939                            XMLWriter& xml_out) 
00940     {
00941       // If xml file not empty, then use alternate
00942       if (params.xml_file != "")
00943       {
00944         string xml_file = makeXMLFileName(params.xml_file, update_no);
00945 
00946         push(xml_out, "stoch_baryon");
00947         write(xml_out, "update_no", update_no);
00948         write(xml_out, "xml_file", xml_file);
00949         pop(xml_out);
00950 
00951         XMLFileWriter xml(xml_file);
00952         func(update_no, xml);
00953       }
00954       else
00955       {
00956         func(update_no, xml_out);
00957       }
00958     }
00959 
00960 
00961     // Function call
00962     void 
00963     InlineMeas::func(unsigned long update_no,
00964                      XMLWriter& xml_out) 
00965     {
00966       START_CODE();
00967 
00968       StopWatch snoop;
00969       snoop.reset();
00970       snoop.start();
00971 
00972       
00973       StopWatch swiss;
00974                         
00975       // Test and grab a reference to the gauge field
00976       XMLBufferWriter gauge_xml;
00977       try
00978       {
00979         TheNamedObjMap::Instance().getData< multi1d<LatticeColorMatrix> >(params.named_obj.gauge_id);
00980         TheNamedObjMap::Instance().get(params.named_obj.gauge_id).getRecordXML(gauge_xml);
00981       }
00982       catch( std::bad_cast ) 
00983       {
00984         QDPIO::cerr << InlineStochGroupBaryonEnv::name << ": caught dynamic cast error" 
00985                     << endl;
00986         QDP_abort(1);
00987       }
00988       catch (const string& e) 
00989       {
00990         QDPIO::cerr << InlineStochGroupBaryonEnv::name << ": map call failed: " << e 
00991                     << endl;
00992         QDP_abort(1);
00993       }
00994       const multi1d<LatticeColorMatrix>& u = 
00995         TheNamedObjMap::Instance().getData< multi1d<LatticeColorMatrix> >(params.named_obj.gauge_id);
00996 
00997       push(xml_out, "StochGroupBaryon");
00998       write(xml_out, "update_no", update_no);
00999 
01000       QDPIO::cout << InlineStochGroupBaryonEnv::name << ": Stochastic Baryon Operator" << endl;
01001 
01002       proginfo(xml_out);    // Print out basic program info
01003 
01004       // Write out the input
01005       params.writeXML(xml_out, "Input");
01006 
01007       // Write out the config info
01008       write(xml_out, "Config_info", gauge_xml);
01009 
01010       push(xml_out, "Output_version");
01011       write(xml_out, "out_version", 1);
01012       pop(xml_out);
01013 
01014       //First calculate some gauge invariant observables just for info.
01015       //This is really cheap.
01016       MesPlq(xml_out, "Observables", u);
01017 
01018       // Save current seed
01019       Seed ran_seed;
01020       QDP::RNG::savern(ran_seed);
01021 
01022       //
01023       // Construct the dilution scheme for each of the 3 quarks
01024       // 
01025       if (params.param.quark_dils.size() != N_quarks)
01026       {
01027         QDPIO::cerr << name << ": expecting 3 quark dilutions" << endl;
01028         QDP_abort(1);
01029       }
01030 
01031       multi1d< Handle< DilutionScheme<LatticeFermion> > > diluted_quarks(N_quarks);  /*!< Here is the big (dil) pickle */
01032 
01033       try
01034       {
01035         // Loop over the 3 quark dilutions
01036         for(int n = 0; n < params.param.quark_dils.size(); ++n)
01037         {
01038           const GroupXML_t& dil_xml = params.param.quark_dils[n];
01039 
01040           std::istringstream  xml_d(dil_xml.xml);
01041           XMLReader  diltop(xml_d);
01042           QDPIO::cout << "Dilution type = " << dil_xml.id << endl;
01043         
01044           diluted_quarks[n] = TheFermDilutionSchemeFactory::Instance().createObject(
01045             dil_xml.id, diltop, dil_xml.path);
01046         }
01047       }
01048       catch(const std::string& e) 
01049       {
01050         QDPIO::cerr << name << ": Caught Exception constructing dilution scheme: " << e << endl;
01051         QDP_abort(1);
01052       }
01053 //------------------------------------------------------------------------
01054 //Sanity checks 
01055 
01056       //The participating timeslices must match for each quark
01057       //grab info from first quark to prime the work
01058 
01059       multi1d<int> participating_timeslices( diluted_quarks[0]->getNumTimeSlices() );
01060 
01061       for (int t0 = 0 ; t0 < participating_timeslices.size() ; ++t0)
01062       {
01063         participating_timeslices[t0] = diluted_quarks[0]->getT0(t0);
01064       }
01065 
01066       for (int n = 1 ; n < N_quarks ; ++n)
01067       {
01068         if ( diluted_quarks[n]->getNumTimeSlices() != participating_timeslices.size() )
01069         {
01070           QDPIO::cerr << name << " : Quarks do not contain the same number of dilution timeslices: Quark " 
01071                       << n << endl; 
01072 
01073           QDP_abort(1);
01074         }
01075 
01076         for (int t0 = 0 ; t0 < participating_timeslices.size() ; ++t0)
01077         {
01078           if  ( diluted_quarks[n]->getT0(t0) != participating_timeslices[t0] )
01079           {
01080             QDPIO::cerr << name << " : Quarks do not contain the same participating timeslices: Quark "<<
01081               n << " timeslice "<< t0 << endl;
01082 
01083             QDP_abort(1);
01084           }
01085         }
01086       }
01087                 
01088       //Another Sanity check, the three quarks must all be 
01089       //inverted on the same cfg
01090       for (int n = 1 ; n < N_quarks ; ++n)
01091       {
01092         if (diluted_quarks[0]->getCfgInfo() != diluted_quarks[n]->getCfgInfo())
01093         {
01094           QDPIO::cerr << name 
01095                       << " : Quarks do not contain the same cfg info, quark "<< n << endl;
01096         
01097           QDP_abort(1);
01098         }
01099                         
01100       }
01101 
01102       //Also ensure that the cfg on which the inversions were performed 
01103       //is the same as the cfg that we are using
01104       { 
01105         std::string cfgInfo; 
01106 
01107         //Really ugly way of doing this(Robert Heeeelp!!)
01108         XMLBufferWriter top;
01109         write(top, "Config_info", gauge_xml);
01110         XMLReader from(top);
01111         XMLReader from2(from, "/Config_info");
01112         std::ostringstream os;
01113         from2.print(os);
01114 
01115         cfgInfo = os.str();
01116 
01117         if (cfgInfo != diluted_quarks[0]->getCfgInfo())
01118         {
01119           QDPIO::cerr << name 
01120                       << " : Quarks do not contain the same cfg info as the gauge field."
01121                       << "gauge: XX"<<cfgInfo<<"XX quarks: XX"<<diluted_quarks[0]->getCfgInfo()<<"XX"<<  endl;
01122 
01123 
01124           QDP_abort(1);
01125         }
01126       }
01127 
01128       //
01129       // Initialize the slow Fourier transform phases
01130       //
01131       int decay_dir = diluted_quarks[0]->getDecayDir();
01132 
01133       //SftMom phases(params.param.mom2_max, false, decay_dir);
01134      //Changed this to cut down on the size of the files created 
01135                 //Stupid way to do this.....
01136                 //phases1 is the instance to be used if version one has been selected
01137 //likewise for phases2
01138                         //Idea: make a constructor for SftMom that takes a bit of 
01139                         //xml and handles the problem. 
01140 
01141                         
01142                         SftMom phases(params.param.moms, decay_dir);
01143 
01144       // Sanity check - if this doesn't work we have serious problems
01145       if (phases.numSubsets() != QDP::Layout::lattSize()[decay_dir])
01146       {
01147         QDPIO::cerr << name << ": number of time slices not equal to that in the decay direction: " 
01148                     << QDP::Layout::lattSize()[decay_dir]
01149                     << endl;
01150         QDP_abort(1);
01151       }
01152 
01153                 
01154       // Another sanity check. The seeds of all the quarks must be different
01155       // and thier decay directions must be the same 
01156       for(int n = 1 ; n < diluted_quarks.size(); ++n)
01157       {
01158         if ( toBool( diluted_quarks[n]->getSeed() == diluted_quarks[0]->getSeed() ) ) 
01159         {
01160           QDPIO::cerr << name << ": error, quark seeds are the same" << endl;
01161           QDP_abort(1);
01162         }
01163 
01164         if ( toBool( diluted_quarks[n]->getDecayDir() != diluted_quarks[0]->getDecayDir() ) )
01165         {
01166           QDPIO::cerr << name << ": error, quark decay dirs do not match" <<endl;
01167           QDP_abort(1);
01168         }
01169 
01170       }
01171 
01172       //
01173       // Smear the gauge field if needed
01174       //
01175       multi1d<LatticeColorMatrix> u_smr = u;
01176 
01177       try
01178       {
01179         std::istringstream  xml_l(params.param.link_smearing.xml);
01180         XMLReader  linktop(xml_l);
01181         QDPIO::cout << "Link smearing type = " << params.param.link_smearing.id << endl;
01182         
01183         
01184         Handle< LinkSmearing >
01185           linkSmearing(TheLinkSmearingFactory::Instance().createObject(params.param.link_smearing.id,
01186                                                                        linktop, params.param.link_smearing.path));
01187 
01188         (*linkSmearing)(u_smr);
01189       }
01190       catch(const std::string& e) 
01191       {
01192         QDPIO::cerr << name << ": Caught Exception link smearing: " << e << endl;
01193         QDP_abort(1);
01194       }
01195 
01196       MesPlq(xml_out, "Smeared_Observables", u_smr);
01197 
01198       //Used for testing purposes       
01199       multi1d<int> orig(4);
01200       for (int ind = 0 ; ind < 4 ; ++ind)
01201       {
01202         orig[ind] = 0;
01203       }
01204 
01205       //
01206       // Read operator coefficients
01207       //
01208       QDPIO::cout << "Reading 3-quark operators" << endl;
01209       ThreeQuarkOps_t qqq_oplist; 
01210 
01211       readOps(qqq_oplist, params.named_obj.operators_file.ops_file);
01212 
01213       //
01214       // Create the quark smearing factory 
01215       //
01216       Handle< QuarkSmearing<LatticeFermion> > quarkSmearing;
01217 
01218       try
01219       {
01220         QDPIO::cout << "Create quark smearing object" << endl;
01221 
01222         // Create the quark smearing object
01223         std::istringstream  xml_s(params.param.quark_smearing.xml);
01224         XMLReader  smeartop(xml_s);
01225         
01226         quarkSmearing =
01227           TheFermSmearingFactory::Instance().createObject(params.param.quark_smearing.id,
01228                                                           smeartop, params.param.quark_smearing.path);
01229                         
01230       }
01231       catch(const std::string& e) 
01232       {
01233         QDPIO::cerr << ": Caught Exception creating quark smearing object: " << e << endl;
01234         QDP_abort(1);
01235       }
01236       catch(...)
01237       {
01238         QDPIO::cerr << ": Caught generic exception creating smearing object" << endl;
01239         QDP_abort(1);
01240       }
01241 
01242       //
01243       // Baryon operators
01244       //
01245 
01246       //
01247       // Permutations of quarks within an operator
01248       //
01249       const std::string& pstring = params.named_obj.quark_ids; 
01250       int num_orderings = 1; 
01251                         
01252       //Should think of a cleverer algorithm for n quarks 
01253       if  (pstring.size() != N_quarks)
01254       {
01255         QDPIO::cerr << "Invalid size for 'quark_ids'. Must be 3 but is " << pstring.size() << endl;
01256         QDP_abort(1);
01257       }
01258 
01259       //If 2 identical quarks, different one must be in the fisrt position
01260       if (  ( (pstring[0] == pstring[2]) && (pstring[1] != pstring[2]) ) ||
01261             ( (pstring[0] == pstring[1]) && (pstring[1] != pstring[2]) ) )
01262       {
01263         QDPIO::cerr << "Invalid format for 'quark_ids'. Identical q's must be last 2 entries.: "
01264                     << pstring << endl;
01265         QDP_abort(1);
01266       }
01267                         
01268       //Check that the kappas of the supposed identical quarks are the same.
01269       if ( (pstring[0] != pstring[1]) && (pstring[1] == pstring[2]) )
01270       {
01271         num_orderings = 2;
01272       
01273         if ( toBool(diluted_quarks[0]->getKappa() == diluted_quarks[1]->getKappa()) ||
01274              toBool(diluted_quarks[1]->getKappa() != diluted_quarks[2]->getKappa()) )
01275         {
01276           QDPIO::cerr << "quark_id's do not correspond to the correct identical quarks"
01277                       << endl;
01278           QDP_abort(1);
01279         }
01280       }
01281                         
01282       if  (pstring[0] == pstring[2]) 
01283       {
01284         num_orderings = 6;
01285       
01286         if ( toBool(diluted_quarks[0]->getKappa() != diluted_quarks[1]->getKappa()) ||
01287              toBool(diluted_quarks[0]->getKappa() != diluted_quarks[2]->getKappa()) )
01288         {
01289                                         
01290           QDPIO::cerr << "quark_id's do not correspond to the correct identical quarks"
01291                       << endl;
01292           QDP_abort(1);
01293         }
01294       }
01295                                 
01296       QDPIO::cout << "Num Ordering = " << num_orderings << endl;
01297 
01298       multi1d< multi1d<int> >  perms(num_orderings);
01299       {
01300         multi1d<int> p(N_quarks);
01301 
01302         if (num_orderings >= 1)
01303         {
01304           p[0] = 0; p[1] = 1; p[2] = 2;
01305           perms[0] = p;
01306         }
01307 
01308         if (num_orderings >= 2)
01309         {
01310           p[0] = 0; p[1] = 2; p[2] = 1;
01311           perms[1] = p;
01312         }
01313 
01314         if (num_orderings >= 3)
01315         {
01316           p[0] = 1; p[1] = 0; p[2] = 2;
01317           perms[2] = p;
01318         }
01319 
01320         if (num_orderings >= 4)
01321         {
01322           p[0] = 1; p[1] = 2; p[2] = 0;
01323           perms[3] = p;
01324         }
01325 
01326         if (num_orderings >= 5)
01327         {
01328           p[0] = 2; p[1] = 1; p[2] = 0;
01329           perms[4] = p;
01330         }
01331 
01332         if (num_orderings >= 6)
01333         {
01334           p[0] = 2; p[1] = 0; p[2] = 1;
01335           perms[5] = p;
01336         }
01337       }
01338 
01339       //We make all source operators before we make all sink operators to 
01340       //save on memory. 
01341 
01342       for(int t0 = 0; t0 < participating_timeslices.size() ; ++t0)
01343       {
01344         StopWatch watch;
01345         //Make the source operators 
01346         {
01347 
01348           // The object holding the smeared and displaced color vector maps  
01349           SmearedDispObjects smrd_disp_srcs(params.param.displacement_length,
01350                                             diluted_quarks, quarkSmearing, u_smr );
01351 
01352           // Creation operator
01353           BaryonOperator_t  creat_oper;
01354           creat_oper.mom2_max    = 0;
01355           creat_oper.decay_dir   = decay_dir;
01356           creat_oper.seed_l      = diluted_quarks[0]->getSeed();
01357           creat_oper.seed_m      = diluted_quarks[1]->getSeed();
01358           creat_oper.seed_r      = diluted_quarks[2]->getSeed();
01359           creat_oper.dilution_l  = params.param.quark_dils[0];
01360           creat_oper.dilution_m  = params.param.quark_dils[1];
01361           creat_oper.dilution_r  = params.param.quark_dils[2];
01362           creat_oper.smearing    = params.param.quark_smearing;
01363           creat_oper.perms       = perms;
01364           creat_oper.time_slices.resize( 1 ); //Only a single t0 per file 
01365 
01366           // Construct creation operator
01367           // Loop over each operator 
01368           for(int l=0; l < qqq_oplist.ops.size(); ++l)
01369           {
01370             QDPIO::cout << "Elemental operator: op = " << l << endl;
01371 
01372             push(xml_out, "BaryonOperator");
01373 
01374             creat_oper.id = qqq_oplist.ops[l].name;
01375 
01376             write(xml_out, "Name", creat_oper.id);
01377 
01378             // Loop over all orderings and build the operator
01379             swiss.reset();
01380             swiss.start();
01381 
01382             // The keys for the spin and displacements for this particular elemental operator
01383             multi1d<KeySmearedDispColorVector_t> keySmearedDispColorVector(N_quarks);
01384 
01385             for(int n = 0 ; n < N_quarks ; ++n)
01386             {
01387               keySmearedDispColorVector[n].displacement = qqq_oplist.ops[l].quark[n].displacement;
01388               keySmearedDispColorVector[n].spin         = qqq_oplist.ops[l].quark[n].spin;
01389             }
01390 
01391 
01392             creat_oper.time_slices[0].t0 = participating_timeslices[t0];
01393             creat_oper.time_slices[0].orderings.resize(num_orderings);
01394 
01395             for(int ord = 0; ord < num_orderings ; ++ord)
01396             {
01397               QDPIO::cout << "Ordering = " << ord << endl;
01398 
01399               creat_oper.time_slices[0].orderings[ord].perm = perms[ord];
01400 
01401               const int n0 = perms[ord][0];
01402               const int n1 = perms[ord][1];
01403               const int n2 = perms[ord][2];
01404 
01405               // The operator must hold all the dilutions
01406 
01407               // Creation operator
01408               BaryonOperator_t::TimeSlices_t::Orderings_t& cop = creat_oper.time_slices[0].orderings[ord];
01409 
01410               cop.dilutions.resize(diluted_quarks[n0]->getDilSize(t0), diluted_quarks[n1]->getDilSize(t0),
01411                                    diluted_quarks[n2]->getDilSize(t0) );
01412 
01413               for (int n = 0 ; n < N_quarks ; ++n)
01414               {
01415                 keySmearedDispColorVector[n].t0 = t0;
01416               }
01417 
01418               for(int i = 0 ; i <  diluted_quarks[n0]->getDilSize(t0) ; ++i)
01419               {
01420                 for(int j = 0 ; j < diluted_quarks[n1]->getDilSize(t0) ; ++j)                                                   
01421                 {
01422 
01423                   keySmearedDispColorVector[0].dil = i;
01424                   keySmearedDispColorVector[1].dil = j;
01425 
01426                   //Form the di-quark to save on recalculating 
01427                   multi1d<LatticeComplex> diquark(Nc);
01428 
01429                   const multi1d<LatticeComplex> &q0 = smrd_disp_srcs.getDispSource(n0, 
01430                                                                                    keySmearedDispColorVector[0]); 
01431 
01432                   const multi1d<LatticeComplex> &q1 = smrd_disp_srcs.getDispSource(n1, 
01433                                                                                    keySmearedDispColorVector[1]);
01434 
01435                   /*QDPIO::cout<<"q0[0] testval= "<< peekSite(q0[0], orig)
01436                     << endl; 
01437 
01438                     QDPIO::cout<<"q1[0] testval= "<< peekSite(q1[0], orig)
01439                     << endl; 
01440 
01441                   */
01442 
01443                   watch.reset();
01444                   watch.start();
01445                   //For the source, restrict this operation to a subset
01446                   makeDiquark( diquark, q0 , q1, phases.getSet()[ participating_timeslices[t0] ] ); 
01447                   watch.stop();
01448 
01449                   /*QDPIO::cout<< " Made diquark : time = " << 
01450                     watch.getTimeInSeconds() << "secs" << endl;
01451                   */            
01452 
01453                   for(int k = 0 ; k < diluted_quarks[n2]->getDilSize(t0) ; ++k) 
01454                   {
01455 
01456                     keySmearedDispColorVector[2].dil = k;
01457 
01458                     // Contract over color indices with antisym tensor.
01459                     // NOTE: the creation operator only lives on a time slice, so restrict
01460                     // the operation to that time slice
01461 
01462                     LatticeComplex c_oper;
01463 
01464                     const multi1d<LatticeComplex> &q2 = smrd_disp_srcs.getDispSource(n2, 
01465                                                                                      keySmearedDispColorVector[2]);
01466 
01467                     /*QDPIO::cout<<"q2[0] testval= "<< peekSite(q2[0], orig)
01468                       << endl; 
01469                     */
01470                     watch.reset();
01471                     watch.start();
01472 
01473                     makeColorSinglet( c_oper, diquark, q2, phases.getSet()[ 
01474                                         participating_timeslices[t0] ] );
01475 
01476                     watch.stop();
01477 
01478                     /*QDPIO::cout<< "Made Color singlet : time =  " <<  
01479                       watch.getTimeInSeconds() << "secs" << endl;
01480                     */  
01481                     /*QDPIO::cout << "testval = " << peekSite(c_oper, orig) 
01482                       << endl;
01483                     */  
01484                     // Slow fourier-transform
01485                     // We can restrict what the FT routine requires to a subset.
01486                     watch.reset();
01487                     watch.start();
01488 
01489                     /*
01490                                  multi2d<DComplex> c_sum(phases.sft(c_oper, 
01491                                                        participating_timeslices[t0] ));
01492                                 */
01493 
01494                                 multi2d<DComplex> c_sum;
01495                                 int num_mom;
01496 
01497                                         c_sum = phases.sft(c_oper, participating_timeslices[t0]);
01498                                         num_mom = phases.numMom();
01499                         
01500                     watch.stop();
01501 
01502                     /*QDPIO::cout << " Spatial sums completed: time = " << 
01503                       watch.getTimeInSeconds() << "secs " << endl;
01504                     */
01505                     // Unpack into separate momentum and correlator
01506 
01507                     cop.dilutions(i,j,k).mom_projs.resize(num_mom);
01508 
01509                     for(int mom_num = 0 ; mom_num < num_mom ; ++mom_num) 
01510                     {
01511                       cop.dilutions(i,j,k).mom_projs[mom_num].mom = 
01512                                                 params.param.moms[mom_num];
01513 
01514                       cop.dilutions(i,j,k).mom_projs[mom_num].op.resize(1);
01515 
01516                       cop.dilutions(i,j,k).mom_projs[mom_num].op[ 0 ] = c_sum[mom_num][ 
01517                         participating_timeslices[t0] ];
01518                     }
01519 
01520                   } // end for k
01521                 } // end for j
01522               } // end for i
01523             }//end ord 
01524 
01525             swiss.stop();
01526 
01527 
01528             QDPIO::cout << "Source operator construction: operator= " << l 
01529                         << "  time= "
01530                         << swiss.getTimeInSeconds() 
01531                         << " secs" << endl;
01532 
01533             QDPIO::cout << "Source operator testval(t0 = " << 
01534               participating_timeslices[t0] << ") = " << 
01535               creat_oper.time_slices[0].orderings[0].dilutions(0,0,0).mom_projs[0].op[0];
01536 
01537 
01538 
01539             //Hard code the elemental op name for now 
01540             std::stringstream cnvrt;
01541             cnvrt <<  creat_oper.id  << "_t" << participating_timeslices[t0] << "_src.lime";
01542 
01543             std::string filename;
01544 
01545             filename = cnvrt.str(); 
01546 
01547             // Write the meta-data and the binary for this operator
01548             swiss.reset();
01549             swiss.start();
01550             {
01551               XMLBufferWriter     src_record_xml, file_xml;
01552               BinaryBufferWriter  src_record_bin;
01553 
01554               push(file_xml, "SourceBaryonOperator");
01555               write(file_xml, "Params", params.param);
01556               write(file_xml, "Config_info", gauge_xml);
01557               write(file_xml, "Op_Info",qqq_oplist.ops[l]);
01558 
01559               push(file_xml, "QuarkSources");
01560 
01561               push(file_xml, "Quark_l");
01562               push(file_xml, "TimeSlice");
01563               push(file_xml, "Dilutions");
01564               for (int dil = 0; dil < diluted_quarks[0]->getDilSize(t0) ; ++dil)
01565               {
01566                 write( file_xml, "elem", 
01567                        diluted_quarks[0]->getSourceHeader(t0, dil) );
01568 
01569                 //      QDPIO::cout<< "t0 = " << t0 << " dil = "<< dil <<
01570                 //      " srdhdr = XX"<<diluted_quarks[0]->getSourceHeader(t0,dil) << endl;
01571               }
01572               pop(file_xml); //dilutions 
01573               pop(file_xml); //TimeSlice
01574               pop(file_xml); //Quark_l
01575 
01576               push(file_xml, "Quark_m");
01577               push(file_xml, "TimeSlice");
01578               push(file_xml, "Dilutions");
01579               for (int dil = 0; dil < diluted_quarks[1]->getDilSize(t0) ; ++dil)
01580               {
01581                 write( file_xml, "elem", 
01582                        diluted_quarks[1]->getSourceHeader(t0, dil) );
01583               }
01584               pop(file_xml); //dilutions 
01585               pop(file_xml); //TimeSlice
01586               pop(file_xml); //Quark_m
01587 
01588               push(file_xml, "Quark_r");
01589               push(file_xml, "TimeSlice");
01590               push(file_xml, "Dilutions");
01591               for (int dil = 0; dil < diluted_quarks[2]->getDilSize(t0) ; ++dil)
01592               {
01593                 write( file_xml, "elem", 
01594                        diluted_quarks[2]->getSourceHeader(t0, dil) );
01595               }
01596               pop(file_xml); //dilutions 
01597               pop(file_xml); //TimeSlice
01598               pop(file_xml); //Quark_r
01599 
01600               pop(file_xml);//QuarkSources
01601               push(file_xml, "QuarkSinks");
01602 
01603               push(file_xml, "Quark_l");
01604               write(file_xml, "PropHeader", diluted_quarks[0]->getPropHeader(0,0) );
01605               pop(file_xml);
01606 
01607               push(file_xml, "Quark_m");
01608               write(file_xml, "PropHeader", diluted_quarks[1]->getPropHeader(0,0) );
01609               pop(file_xml);
01610 
01611               push(file_xml, "Quark_r");
01612               write(file_xml, "PropHeader", diluted_quarks[2]->getPropHeader(0,0) );
01613               pop(file_xml);
01614 
01615               pop(file_xml); //Quark Sinks  
01616               pop(file_xml);//SourceBaryonOp
01617 
01618               QDPFileWriter qdp_file(file_xml, filename,     // are there one or two files???
01619                                      QDPIO_SINGLEFILE, QDPIO_SERIAL, QDPIO_OPEN);
01620 
01621 
01622               write(src_record_xml, "BaryonCreationOperator", creat_oper);
01623               write(src_record_bin, creat_oper);
01624 
01625               write(qdp_file, src_record_xml, src_record_bin);
01626 
01627             }
01628             swiss.stop();
01629 
01630             QDPIO::cout << "Source Operator writing: operator = " << 
01631               l << "  time= "
01632                         << swiss.getTimeInSeconds() 
01633                         << " secs" << endl;
01634 
01635             pop(xml_out); // BaryonOperator 
01636 
01637           } // end for l (operator )
01638 
01639         } //End Make creation operator
01640 
01641 
01642 
01643         //Make Annilation Operator
01644         {
01645 
01646           // The object holding the smeared and displaced color vector maps  
01647           SmearedDispObjects smrd_disp_snks(params.param.displacement_length,
01648                                             diluted_quarks, quarkSmearing, u_smr );
01649 
01650 
01651           // Annihilation operator
01652           BaryonOperator_t  annih_oper;
01653           annih_oper.mom2_max    = 0;
01654           annih_oper.decay_dir   = decay_dir;
01655           annih_oper.seed_l      = diluted_quarks[0]->getSeed();
01656           annih_oper.seed_m      = diluted_quarks[1]->getSeed();
01657           annih_oper.seed_r      = diluted_quarks[2]->getSeed();
01658           annih_oper.dilution_l  = params.param.quark_dils[0];
01659           annih_oper.dilution_m  = params.param.quark_dils[1];
01660           annih_oper.dilution_r  = params.param.quark_dils[2];
01661           annih_oper.smearing    = params.param.quark_smearing;
01662           annih_oper.perms       = perms;
01663           annih_oper.time_slices.resize( 1 );
01664 
01665           // Construct annihilation operator
01666           QDPIO::cout << "Building Sink operators" << endl;
01667 
01668           // Loop over each operator 
01669           for(int l=0; l < qqq_oplist.ops.size(); ++l)
01670           {
01671             QDPIO::cout << "Elemental operator: op = " << l << endl;
01672 
01673             annih_oper.id = qqq_oplist.ops[l].name;
01674 
01675             // Loop over all orderings and build the operator
01676             swiss.reset();
01677             swiss.start();
01678 
01679             // The keys for the spin and displacements for this particular elemental operator
01680             multi1d<KeySmearedDispColorVector_t> keySmearedDispColorVector(N_quarks);
01681 
01682             for(int n = 0 ; n < N_quarks ; ++n)
01683             {
01684               keySmearedDispColorVector[n].displacement = qqq_oplist.ops[l].quark[n].displacement;
01685               keySmearedDispColorVector[n].spin         = qqq_oplist.ops[l].quark[n].spin;
01686             }
01687 
01688             annih_oper.time_slices[0].t0 = participating_timeslices[t0];
01689             //annih_oper.time_slices[0].orderings.resize(num_orderings);
01690             annih_oper.time_slices[0].orderings.resize(1);
01691 
01692 
01693                         int ord = 0;
01694             //for(int ord = 0 ; ord < num_orderings ; ++ord)
01695             {
01696               QDPIO::cout << "Ordering = " << ord << endl;
01697 
01698               annih_oper.time_slices[0].orderings[ord].perm = perms[ord];
01699 
01700               const int n0 = perms[ord][0];
01701               const int n1 = perms[ord][1];
01702               const int n2 = perms[ord][2];
01703 
01704               // The operator must hold all the dilutions
01705               // We know that all time slices match. However, not all time slices of the
01706               // lattice maybe used
01707 
01708               // Creation operator
01709               BaryonOperator_t::TimeSlices_t::Orderings_t& aop = annih_oper.time_slices[0].orderings[ord];
01710 
01711               aop.dilutions.resize(diluted_quarks[n0]->getDilSize(t0), diluted_quarks[n1]->getDilSize(t0),
01712                                    diluted_quarks[n2]->getDilSize(t0) );
01713 
01714               for (int n = 0 ; n < N_quarks ; ++n)
01715               {
01716                 keySmearedDispColorVector[n].t0 = t0;
01717               }
01718 
01719               for(int i = 0 ; i <  diluted_quarks[n0]->getDilSize(t0) ; ++i)
01720               {
01721                 for(int j = 0 ; j < diluted_quarks[n1]->getDilSize(t0) ; ++j)         
01722                 {
01723 
01724                   keySmearedDispColorVector[0].dil = i;
01725                   keySmearedDispColorVector[1].dil = j;
01726 
01727                   //Form the di-quark to save on recalculating 
01728                   multi1d<LatticeComplex> diquark(Nc);
01729 
01730                   const multi1d<LatticeComplex> &q0 = smrd_disp_snks.getDispSolution(n0, 
01731                                                                                      keySmearedDispColorVector[0]); 
01732 
01733                   const multi1d<LatticeComplex> &q1 = smrd_disp_snks.getDispSolution(n1, 
01734                                                                                      keySmearedDispColorVector[1]);
01735 
01736 
01737                   //QDPIO::cout<<"q0[0] testval= "<< peekSite(q0[0], orig)
01738                   //    << endl; 
01739 
01740                   //QDPIO::cout<<"q1[0] testval= "<< peekSite(q1[0], orig)
01741                   //    << endl; 
01742 
01743 
01744                   watch.reset();
01745                   watch.start();
01746 
01747                   makeDiquark( diquark, q0 , q1, all ); 
01748 
01749                   watch.stop();
01750                   /*QDPIO::cout << "Made diquark: time = " << 
01751                     watch.getTimeInSeconds() << "secs " << endl;
01752                   */
01753 
01754                   for(int k = 0 ; k < diluted_quarks[n2]->getDilSize(t0) ; ++k) 
01755                   {
01756 
01757                     keySmearedDispColorVector[2].dil = k;
01758 
01759                     // Contract over color indices with antisym tensor.
01760                     // There is a potential optimization here - the colorcontract of
01761                     // the first two quarks could be pulled outside the innermost dilution
01762                     // loop.
01763                     // NOTE: the creation operator only lives on a time slice, so restrict
01764                     // the operation to that time slice
01765 
01766                     LatticeComplex a_oper;
01767 
01768                     const multi1d<LatticeComplex> &q2 = smrd_disp_snks.getDispSolution(n2, 
01769                                                                                        keySmearedDispColorVector[2]);
01770 
01771                     //QDPIO::cout<<"q2[0] testval= "<< peekSite(q2[0], orig)
01772                     //<< endl;
01773 
01774                     watch.reset();
01775                     watch.start();
01776 
01777                     makeColorSinglet( a_oper, diquark, q2, all);
01778 
01779                     watch.stop();
01780 
01781                     /*
01782                       QDPIO::cout <<    "Made Color Singlet: time = " <<
01783                       watch.getTimeInSeconds() << "secs" << endl;
01784                     */
01785                     /*QDPIO::cout << "testval = " << peekSite(a_oper, orig) 
01786                       << endl;
01787                     */
01788 
01789                     watch.reset();
01790                     watch.start();
01791 
01792                     // Slow fourier-transform
01793                     multi2d<DComplex> a_sum;
01794                                 int num_mom;
01795 
01796                                         a_sum = phases.sft(
01797                                                         a_oper);
01798                                         num_mom = phases.numMom();
01799 
01800                     watch.stop();
01801                     /*
01802                       QDPIO::cout << "Spatial Sums completed: time " << 
01803                       watch.getTimeInSeconds() << "secs" << endl;
01804                     */          
01805                     // Unpack into separate momentum and correlator
01806                     aop.dilutions(i,j,k).mom_projs.resize(num_mom);
01807 
01808                     for(int mom_num = 0 ; mom_num < num_mom ; ++mom_num) 
01809                     {
01810                       aop.dilutions(i,j,k).mom_projs[mom_num].mom = params.param.moms[mom_num];
01811 
01812                       aop.dilutions(i,j,k).mom_projs[mom_num].op = a_sum[mom_num];
01813 
01814                     }
01815 
01816                   } // end for k
01817                 } // end for j
01818               } // end for i
01819             }//end ord 
01820             swiss.stop();
01821 
01822 
01823             QDPIO::cout << "Sink operator construction: operator= " << l 
01824                         << "  time= "
01825                         << swiss.getTimeInSeconds() 
01826                         << " secs" << endl;
01827 
01828             QDPIO::cout << "Sink op testval( t0 = " << 
01829               participating_timeslices[t0] << ") = " << 
01830               annih_oper.time_slices[0].orderings[0].dilutions(0,0,0).mom_projs[0].op[0] 
01831                         << endl;
01832 
01833             //Hard code the elemental op name for now 
01834             std::stringstream cnvrt;
01835             cnvrt <<  annih_oper.id  << "_t" << participating_timeslices[t0] << "_snk.lime";
01836 
01837             std::string filename;
01838 
01839             filename = cnvrt.str(); 
01840 
01841             // Write the meta-data and the binary for this operator
01842             swiss.reset();
01843             swiss.start();
01844             {
01845               XMLBufferWriter     src_record_xml, file_xml;
01846               BinaryBufferWriter  src_record_bin;
01847 
01848               push(file_xml, "SinkBaryonOperator");
01849               write(file_xml, "Params", params.param);
01850               write(file_xml, "Config_info", gauge_xml);
01851               write(file_xml, "Op_Info",qqq_oplist.ops[l]);
01852               push(file_xml, "QuarkSources");
01853 
01854               push(file_xml, "Quark_l");
01855               push(file_xml, "TimeSlice");
01856               push(file_xml, "Dilutions");
01857               for (int dil = 0; dil < diluted_quarks[0]->getDilSize(t0) ; ++dil)
01858               {
01859                 write( file_xml, "elem", 
01860                        diluted_quarks[0]->getSourceHeader(t0, dil) );
01861               }
01862               pop(file_xml); //dilutions 
01863               pop(file_xml); //TimeSlice
01864               pop(file_xml); //Quark_l
01865 
01866               push(file_xml, "Quark_m");
01867               push(file_xml, "TimeSlice");
01868               push(file_xml, "Dilutions");
01869               for (int dil = 0; dil < diluted_quarks[1]->getDilSize(t0) ; ++dil)
01870               {
01871                 write( file_xml, "elem", 
01872                        diluted_quarks[1]->getSourceHeader(t0, dil) );
01873               }
01874               pop(file_xml); //dilutions 
01875               pop(file_xml); //TimeSlice
01876               pop(file_xml); //Quark_m
01877 
01878               push(file_xml, "Quark_r");
01879               push(file_xml, "TimeSlice");
01880               push(file_xml, "Dilutions");
01881               for (int dil = 0; dil < diluted_quarks[2]->getDilSize(t0) ; ++dil)
01882               {
01883                 write( file_xml, "elem", 
01884                        diluted_quarks[2]->getSourceHeader(t0, dil) );
01885               }
01886               pop(file_xml); //dilutions 
01887               pop(file_xml); //TimeSlice
01888               pop(file_xml); //Quark_r
01889 
01890               pop(file_xml);//QuarkSources
01891               push(file_xml, "QuarkSinks");
01892 
01893               push(file_xml, "Quark_l");
01894               write(file_xml, "PropHeader", diluted_quarks[0]->getPropHeader(0,0) );
01895               pop(file_xml);
01896 
01897               push(file_xml, "Quark_m");
01898               write(file_xml, "PropHeader", diluted_quarks[1]->getPropHeader(0,0) );
01899               pop(file_xml);
01900 
01901               push(file_xml, "Quark_r");
01902               write(file_xml, "PropHeader", diluted_quarks[2]->getPropHeader(0,0) );
01903               pop(file_xml);
01904 
01905               pop(file_xml);//QuarkSinks 
01906               pop(file_xml);//SinkBaryonOperator
01907 
01908               QDPFileWriter qdp_file(file_xml, filename,     // are there one or two files???
01909                                      QDPIO_SINGLEFILE, QDPIO_SERIAL, QDPIO_OPEN);
01910 
01911 
01912               write(src_record_xml, "BaryonAnnihilationOperator", annih_oper);
01913               write(src_record_bin, annih_oper);
01914 
01915               write(qdp_file, src_record_xml, src_record_bin);
01916 
01917             }
01918             swiss.stop();
01919 
01920             QDPIO::cout << "Sink Operator writing: operator = " << l
01921                         << "  time= " << swiss.getTimeInSeconds() << " secs" << endl;
01922 
01923           } // end for l (operator )
01924 
01925         } //End Make annihilation operator
01926 
01927       } //end t0 
01928       // Close the namelist output file XMLDAT
01929       pop(xml_out);     // StochBaryon
01930 
01931       snoop.stop();
01932       QDPIO::cout << InlineStochGroupBaryonEnv::name << ": total time = " 
01933                   << snoop.getTimeInSeconds() 
01934                   << " secs" << endl;
01935 
01936       QDPIO::cout << InlineStochGroupBaryonEnv::name << ": ran successfully" << endl;
01937 
01938       END_CODE();
01939     } // func
01940 
01941   } // namespace InlineStochGroupBaryonEnv
01942 
01943   /*! @} */  // end of group hadron
01944 
01945 } // namespace Chroma

Generated on Sun Nov 22 04:33:13 2009 for CHROMA by  doxygen 1.4.7