inline_disco_w.cc

Go to the documentation of this file.
00001 // $Id: inline_disco_w.cc,v 1.11 2009/03/09 15:25:11 caubin Exp $
00002 /*! \file
00003  * \brief Inline measurement 3pt_prop
00004  *
00005  */
00006 #include <vector> 
00007 #include <map> 
00008 
00009 #include "handle.h"
00010 #include "meas/inline/hadron/inline_disco_w.h"
00011 #include "meas/inline/abs_inline_measurement_factory.h"
00012 #include "meas/smear/quark_smearing_factory.h"
00013 #include "meas/smear/quark_smearing_aggregate.h"
00014 #include "meas/smear/displacement.h"
00015 #include "meas/sources/source_smearing_aggregate.h"
00016 #include "meas/sources/source_smearing_factory.h"
00017 #include "meas/sources/dilutezN_source_const.h"
00018 #include "meas/sources/zN_src.h"
00019 #include "meas/sinks/sink_smearing_aggregate.h"
00020 #include "meas/sinks/sink_smearing_factory.h"
00021 #include "meas/hadron/barspinmat_w.h"
00022 #include "meas/hadron/baryon_operator_aggregate_w.h"
00023 #include "meas/hadron/baryon_operator_factory_w.h"
00024 #include "meas/hadron/dilution_scheme_aggregate.h"
00025 #include "meas/hadron/dilution_scheme_factory.h"
00026 #include "meas/glue/mesplq.h"
00027 #include "util/ft/sftmom.h"
00028 #include "util/info/proginfo.h"
00029 #include "meas/inline/make_xml_file.h"
00030 #include "util/info/unique_id.h"
00031 #include "util/ferm/transf.h"
00032 #include "meas/inline/io/named_objmap.h"
00033 
00034 #include "util/ferm/key_val_db.h"
00035 
00036 namespace Chroma{ 
00037   namespace InlineDiscoEnv{ 
00038     namespace{
00039       AbsInlineMeasurement* createMeasurement(XMLReader& xml_in, 
00040                                               const std::string& path) 
00041       {
00042         return new InlineMeas(Params(xml_in, path));
00043       }
00044 
00045       //! Local registration flag
00046       bool registered = false;
00047     }
00048 
00049     const std::string name = "DISCO";
00050 
00051     //! Register all the factories
00052     bool registerAll() 
00053     {
00054       bool success = true; 
00055       if (! registered)
00056       {
00057         //success &= BaryonOperatorEnv::registerAll();
00058         success &= TheInlineMeasurementFactory::Instance().registerObject(name, createMeasurement);
00059         registered = true;
00060       }
00061       return success;
00062     }
00063   
00064   // Reader for input parameters
00065   void read(XMLReader& xml, const string& path, Params::Param_t& param){
00066       XMLReader paramtop(xml, path);
00067       
00068       int version;
00069       read(paramtop, "version", version);
00070       
00071       switch (version) 
00072         {
00073         case 1:
00074           /************************************************************/
00075           read(paramtop,"max_path_length",param.max_path_length);
00076           read(paramtop,"p2_max",param.p2_max);
00077           read(paramtop,"mass_label",param.mass_label);
00078           param.chi = readXMLArrayGroup(paramtop, "Quarks", "DilutionType");
00079           
00080           break;
00081           
00082         default :
00083           /**************************************************************/
00084 
00085           QDPIO::cerr << "Input parameter version " << version << " unsupported." << endl;
00086           QDP_abort(1);
00087         }
00088       
00089       
00090     }
00091 
00092 
00093     // Writter for input parameters
00094     void write(XMLWriter& xml, const string& path, const Params::Param_t& param){
00095       push(xml, path);
00096       
00097       int version = 1;
00098       
00099       write(xml, "version", version);
00100 
00101       write(xml,"max_path_length",param.max_path_length);
00102       write(xml,"p2_max",param.p2_max);
00103       write(xml,"mass_label",param.mass_label);
00104 
00105       push(xml,"Quarks");
00106       for( int t(0);t<param.chi.size();t++){
00107         push(xml,"elem");
00108         xml<<param.chi[t].xml;
00109         pop(xml);
00110       }
00111       pop(xml);
00112             
00113       pop(xml); // final pop
00114     }
00115 
00116 
00117     //! Gauge field parameters
00118   void read(XMLReader& xml, const string& path, Params::NamedObject_t& input)
00119     {
00120       XMLReader inputtop(xml, path);
00121       
00122       read(inputtop, "gauge_id", input.gauge_id);
00123       read(inputtop, "op_db_file", input.op_db_file);
00124     }
00125     
00126     //! Gauge field parameters
00127   void write(XMLWriter& xml, const string& path, const Params::NamedObject_t& input){
00128       push(xml, path);
00129       
00130       write(xml, "gauge_id", input.gauge_id);
00131       write(xml, "op_db_file", input.op_db_file);
00132       pop(xml);
00133     }
00134     
00135     
00136     // Param stuff
00137     Params::Params(){ 
00138       frequency = 0;
00139     }
00140     
00141     Params::Params(XMLReader& xml_in, const std::string& path) 
00142     {
00143       try 
00144         {
00145           XMLReader paramtop(xml_in, path);
00146           
00147           if (paramtop.count("Frequency") == 1)
00148             read(paramtop, "Frequency", frequency);
00149           else
00150             frequency = 1;
00151           
00152           // Read program parameters
00153           read(paramtop, "Param", param);
00154           
00155           // Read in the output propagator/source configuration info
00156           read(paramtop, "NamedObject", named_obj);
00157           
00158           // Possible alternate XML file pattern
00159           if (paramtop.count("xml_file") != 0) 
00160             {
00161               read(paramtop, "xml_file", xml_file);
00162             }
00163         }
00164       catch(const std::string& e) 
00165         {
00166           QDPIO::cerr << __func__ << ": Caught Exception reading XML: " << e << endl;
00167           QDP_abort(1);
00168         }
00169     }
00170 
00171 
00172     void Params::write(XMLWriter& xml_out, const std::string& path) 
00173     {
00174       push(xml_out, path);
00175       
00176       // Parameters for source construction
00177       InlineDiscoEnv::write(xml_out, "Param", param);
00178       
00179       // Write out the output propagator/source configuration info
00180       InlineDiscoEnv::write(xml_out, "NamedObject", named_obj);
00181 
00182       pop(xml_out);
00183     }
00184 
00185     
00186     //! Meson operator     
00187     struct KeyOperator_t
00188     {
00189       unsigned short int t_slice ; /*!< Meson operator time slice */
00190       multi1d<short int> disp    ; /*!< Displacement dirs of quark (right)*/
00191       multi1d<short int> mom     ; /*!< D-1 momentum of this operator */
00192       
00193       KeyOperator_t(){
00194         mom.resize(Nd-1);
00195       }
00196     };
00197     
00198     bool operator<(const KeyOperator_t& a, const KeyOperator_t& b){
00199       return ((a.t_slice<b.t_slice)||(a.mom<b.mom)||(a.disp<b.disp));
00200     }
00201     
00202     std::ostream& operator<<(std::ostream& os, const KeyOperator_t& d)
00203     {
00204       os << "KeyOperator_t:"
00205          << " t_slice = " << d.t_slice
00206          << ", disp = ";
00207       for (int i=0; i<d.disp.size();i++){
00208         os << d.disp[i] << " " ;
00209       }
00210       os << ", mom = ";
00211       for (int i=0; i<d.mom.size();i++){
00212         os << d.mom[i] << " " ;
00213       }
00214       os << std::endl;
00215 
00216       return os;
00217     }
00218     class ValOperator_t{
00219     public:
00220       multi1d<ComplexD> op ;  
00221       ValOperator_t(){op.resize(Ns*Ns);} // Here go the 16 gamma matrices
00222       ~ValOperator_t(){}
00223     } ;
00224 
00225     //-------------------------------------------------------------------------
00226     //! stream IO
00227     std::ostream& operator<<(std::ostream& os, const ValOperator_t& d)
00228     {
00229       os << "ValOperator_t:\n";
00230       for (int i=0; i<d.op.size();i++){
00231         os <<"     gamma["<<i<<"] = "<< d.op[i] << endl ;
00232       }
00233       
00234       return os;
00235     }
00236     
00237     struct KeyVal_t{
00238       SerialDBKey <KeyOperator_t> k ;
00239       SerialDBData<ValOperator_t> v ;
00240     };
00241 
00242     //! KeyOperator reader    
00243     void read(BinaryReader& bin, KeyOperator_t& d){
00244       read(bin,d.t_slice);
00245       unsigned short int n ;
00246       read(bin,n);
00247       d.disp.resize(n); 
00248       read(bin,d.disp);
00249       d.mom.resize(Nd-1) ;
00250       read(bin,d.mom);
00251     }
00252     //! KeyOperator writer
00253     void write(BinaryWriter& bin, KeyOperator_t& d){
00254       write(bin,d.t_slice);
00255       unsigned short int n ;
00256       n = d.disp.size();
00257       write(bin,n);
00258       write(bin,d.disp);
00259       write(bin,d.mom);
00260     }
00261 
00262     //! ValOperator reader    
00263     void read(BinaryReader& bin, ValOperator_t& d){
00264       d.op.resize(Ns*Ns);
00265       read(bin,d.op);
00266     }
00267     //! ValOperator writer
00268     void write(BinaryWriter& bin, ValOperator_t& d){
00269       write(bin,d.op);
00270     }
00271 
00272     namespace{
00273       StandardOutputStream& operator<<(StandardOutputStream& os, const multi1d<short int>& d){
00274         if (d.size() > 0){
00275           os << d[0]; 
00276           for(int i=1; i < d.size(); ++i)
00277             os << " " << d[i];
00278         }
00279         return os;
00280       }
00281     }
00282 
00283     void do_disco(map< KeyOperator_t, ValOperator_t >& db,
00284                   const LatticeFermion& qbar,
00285                   const LatticeFermion& q,
00286                   const SftMom& p,
00287                   const int& t, 
00288                   const multi1d<short int>& path,
00289                   const int& max_path_length ){
00290       QDPIO::cout<<" Computing Operator with path length "<<path.size()
00291                  <<" on timeslice "<<t<<".   Path: "<<path <<endl;
00292       
00293       ValOperator_t val ;
00294       KeyOperator_t key ;
00295       pair<KeyOperator_t, ValOperator_t> kv ; 
00296       kv.first.t_slice = t ;
00297       if(path.size()==0){
00298         kv.first.disp.resize(1);
00299         kv.first.disp[0] = 0 ;
00300       }
00301       else
00302         kv.first.disp = path ;
00303 
00304       multi1d< multi1d<ComplexD> > foo(p.numMom()) ;
00305       for (int m(0); m < p.numMom(); m++)
00306         foo[m].resize(Ns*Ns);
00307       for(int g(0);g<Ns*Ns;g++){
00308         LatticeComplex cc = localInnerProduct(qbar,Gamma(g)*q);
00309         for (int m(0); m < p.numMom(); m++){
00310           foo[m][g] = sum(p[m]*cc,p.getSet()[t]) ;
00311         }
00312       }
00313       for (int m(0); m < p.numMom(); m++){
00314         for(int i(0);i<(Nd-1);i++)
00315           kv.first.mom[i] = p.numToMom(m)[i] ;
00316         
00317         kv.second.op = foo[m];
00318         pair<map< KeyOperator_t, ValOperator_t >::iterator, bool> itbo;
00319 
00320         itbo = db.insert(kv);
00321         if( itbo.second ){ 
00322           QDPIO::cout<<"Inserting new entry in map\n";
00323         }
00324         else{ // if insert fails, key already exists, so add result
00325           cout<<"Key = "<<kv.first<<endl;
00326           QDPIO::cout<<"Adding result to value already there"<<endl;
00327           for(int i(0);i<kv.second.op.size();i++){
00328             itbo.first->second.op[i] += kv.second.op[i] ;
00329           }
00330         }
00331       }
00332 
00333       if(path.size()<max_path_length){
00334         QDPIO::cout<<" attempt to add new path. "
00335                    <<" current path length is : "<<path.size();
00336         multi1d<short int> new_path(path.size()+1);
00337         QDPIO::cout<<" new path length is : "<<new_path.size()<<endl;
00338         for(int i(0);i<path.size();i++)
00339           new_path[i] = path[i] ;
00340         for(int sign(-1);sign<2;sign+=2)
00341           for(int mu(0);mu<Nd;mu++){
00342             new_path[path.size()]= sign*(mu+1) ;
00343             //skip back tracking 
00344             bool back_track=false ;
00345             if(path.size()>0)
00346               if(path[path.size()-1] == -new_path[path.size()])
00347                 back_track=true;
00348             if(!back_track){
00349               QDPIO::cout<<" Added path: "<<new_path<<endl;
00350               LatticeFermion q_mu ;
00351               if(sign>0)
00352                 q_mu = shift(q, FORWARD, mu);
00353               else
00354                 q_mu = shift(q, BACKWARD, mu);
00355 
00356               do_disco(db, qbar, q_mu, p, t, new_path, max_path_length);
00357             } // skip backtracking
00358           } // mu
00359       }
00360       
00361     }// do_disco
00362 
00363 
00364   //--------------------------------------------------------------
00365   // Function call
00366   //  void 
00367   //InlineDisco::operator()(unsigned long update_no,
00368   //                            XMLWriter& xml_out) 
00369     void InlineMeas::operator()(unsigned long update_no,
00370                                 XMLWriter& xml_out) 
00371     {
00372       // If xml file not empty, then use alternate
00373       if (params.xml_file != ""){
00374         string xml_file = makeXMLFileName(params.xml_file, update_no);
00375         
00376         push(xml_out, "propagator_3pt");
00377         write(xml_out, "update_no", update_no);
00378         write(xml_out, "xml_file", xml_file);
00379         pop(xml_out);
00380         
00381         XMLFileWriter xml(xml_file);
00382         func(update_no, xml);
00383       }
00384       else{
00385         func(update_no, xml_out);
00386       }
00387     }
00388     
00389     
00390     // Function call
00391     //void 
00392     //InlineDisco::func(unsigned long update_no,
00393     //                    XMLWriter& xml_out) 
00394     void InlineMeas::func(unsigned long update_no,
00395                           XMLWriter& xml_out) 
00396     {
00397       START_CODE();
00398       
00399       StopWatch snoop;
00400       snoop.reset();
00401       snoop.start();
00402       
00403       // Test and grab a reference to the gauge field
00404       XMLBufferWriter gauge_xml;
00405       try
00406         {
00407           TheNamedObjMap::Instance().getData< multi1d<LatticeColorMatrix> >(params.named_obj.gauge_id);
00408           TheNamedObjMap::Instance().get(params.named_obj.gauge_id).getRecordXML(gauge_xml);
00409         }
00410       catch( std::bad_cast ) 
00411         {
00412           QDPIO::cerr << InlineDiscoEnv::name << ": caught dynamic cast error" 
00413                       << endl;
00414           QDP_abort(1);
00415         }
00416       catch (const string& e) 
00417         {
00418           QDPIO::cerr << name << ": map call failed: " << e 
00419                       << endl;
00420           QDP_abort(1);
00421         }
00422       const multi1d<LatticeColorMatrix>& u = 
00423         TheNamedObjMap::Instance().getData< multi1d<LatticeColorMatrix> >(params.named_obj.gauge_id);
00424       
00425       push(xml_out, "disco");
00426       write(xml_out, "update_no", update_no);
00427       
00428       QDPIO::cout << name << ": Disconnected diagrams" << endl;
00429       
00430       proginfo(xml_out);    // Print out basic program info
00431       
00432       // Write out the input
00433       params.write(xml_out, "Input");
00434       
00435       // Write out the config info
00436       write(xml_out, "Config_info", gauge_xml);
00437       
00438       push(xml_out, "Output_version");
00439       write(xml_out, "out_version", 1);
00440       pop(xml_out);
00441       
00442       // First calculate some gauge invariant observables just for info.
00443       // This is really cheap.
00444       MesPlq(xml_out, "Observables", u);
00445       
00446       // Save current seed
00447       Seed ran_seed;
00448       QDP::RNG::savern(ran_seed);
00449       
00450       //
00451       // Read the source and solutions
00452       //
00453       StopWatch swatch;
00454       swatch.reset();
00455       swatch.start();
00456       
00457       int N_quarks = params.param.chi.size() ;
00458 
00459       multi1d< Handle< DilutionScheme<LatticeFermion> > > quarks(N_quarks);
00460 
00461       try{
00462         // Loop over quark dilutions
00463         for(int n(0); n < params.param.chi.size(); ++n){
00464           const GroupXML_t& dil_xml = params.param.chi[n];
00465           std::istringstream  xml_d(dil_xml.xml);
00466           XMLReader  diltop(xml_d);
00467           QDPIO::cout << "Dilution type = " << dil_xml.id << endl;
00468           quarks[n] = 
00469             TheFermDilutionSchemeFactory::Instance().createObject(dil_xml.id, 
00470                                                                   diltop, 
00471                                                                   dil_xml.path);
00472         }
00473       }
00474       catch(const std::string& e){
00475         QDPIO::cerr << name << ": Caught Exception constructing dilution scheme: " << e << endl;
00476         QDP_abort(1);
00477       }
00478       
00479       
00480       //-------------------------------------------------------------------
00481       //Sanity checks   
00482 
00483       //Another Sanity check, the three quarks must all be 
00484       //inverted on the same cfg
00485       for (int n = 1 ; n < N_quarks ; ++n){
00486         if (quarks[0]->getCfgInfo() != quarks[n]->getCfgInfo()){
00487           QDPIO::cerr << name << " : Quarks do not contain the same cfg info";
00488           QDPIO::cerr << ", quark "<< n << endl;
00489           QDP_abort(1);
00490         }               
00491       }
00492 
00493 
00494       //Also ensure that the cfg on which the inversions were performed 
00495       //is the same as the cfg that we are using
00496       { 
00497         std::string cfgInfo; 
00498         
00499         //Really ugly way of doing this(Robert Heeeelp!!)
00500         XMLBufferWriter top;
00501         write(top, "Config_info", gauge_xml);
00502         XMLReader from(top);
00503         XMLReader from2(from, "/Config_info");
00504         std::ostringstream os;
00505         from2.print(os);
00506         
00507         cfgInfo = os.str();
00508         
00509         if (cfgInfo != quarks[0]->getCfgInfo()){
00510           QDPIO::cerr << name << " : Quarks do not contain the same";
00511           QDPIO::cerr << " cfg info as the gauge field." ;
00512           QDPIO::cerr << "gauge: XX"<<cfgInfo<<"XX quarks: XX" ;
00513           QDPIO::cerr << quarks[0]->getCfgInfo()<<"XX"<<  endl;
00514           QDP_abort(1);
00515         }
00516       }
00517       
00518 
00519       int decay_dir = quarks[0]->getDecayDir();
00520       //
00521       // Initialize the slow Fourier transform phases
00522       //
00523       //SftMom phases(params.param.mom2_max, false, decay_dir);
00524       SftMom phases(params.param.p2_max, false, decay_dir);
00525       
00526       // Another sanity check. The seeds of all the quarks must be different
00527       // and thier decay directions must be the same 
00528       for(int n = 1 ; n < quarks.size(); ++n){
00529         if(toBool(quarks[n]->getSeed()==quarks[0]->getSeed())){
00530           QDPIO::cerr << name << ": error, quark seeds are the same" << endl;
00531           QDP_abort(1);
00532         }
00533 
00534         if(toBool(quarks[n]->getDecayDir()!=quarks[0]->getDecayDir())){
00535           QDPIO::cerr<<name<< ": error, quark decay dirs do not match" <<endl;
00536           QDP_abort(1);
00537         }
00538       }
00539 
00540       map< KeyOperator_t, ValOperator_t > data ;
00541       
00542       for(int n(0);n<quarks.size();n++){
00543         for (int it(0) ; it < quarks[n]->getNumTimeSlices() ; ++it){
00544           int t = quarks[n]->getT0(it) ;
00545           QDPIO::cout<<" Doing quark: "<<n <<endl ;
00546           QDPIO::cout<<"   quark: "<<n <<" has "<<quarks[n]->getDilSize(it);
00547           QDPIO::cout<<" dilutions on time slice "<<t<<endl ;
00548           for(int i = 0 ; i <  quarks[n]->getDilSize(it) ; ++i){
00549             QDPIO::cout<<"   Doing dilution : "<<i<<endl ;
00550             multi1d<short int> d ;
00551             LatticeFermion qbar  = quarks[n]->dilutedSource(it,i);
00552             LatticeFermion q     = quarks[n]->dilutedSolution(it,i);
00553             QDPIO::cout<<"   Starting recursion "<<endl ;
00554             do_disco(data, qbar, q, phases, t, d, params.param.max_path_length);
00555             QDPIO::cout<<" done with recursion! "
00556                        <<"  The length of the path is: "<<d.size()<<endl ;
00557           }
00558           QDPIO::cout<<" Done with dilutions for quark: "<<n <<endl ;
00559         }
00560       }
00561 
00562       // DB storage          
00563       BinaryStoreDB<SerialDBKey<KeyOperator_t>,SerialDBData<ValOperator_t> > qdp_db;
00564 
00565       // Open the file, and write the meta-data and the binary for this operator
00566       {
00567         XMLBufferWriter file_xml;
00568 
00569         push(file_xml, "DBMetaData");
00570         write(file_xml, "id", string("eigElemOp"));
00571         write(file_xml, "lattSize", QDP::Layout::lattSize());
00572         write(file_xml, "decay_dir", decay_dir);
00573         write(file_xml, "Params", params.param);
00574         write(file_xml, "Config_info", gauge_xml);
00575         pop(file_xml);
00576 
00577         std::string file_str(file_xml.str());
00578         qdp_db.setMaxUserInfoLen(file_str.size());
00579 
00580         qdp_db.open(params.named_obj.op_db_file, O_RDWR | O_CREAT, 0664);
00581 
00582         qdp_db.insertUserdata(file_str);
00583       }
00584 
00585       // Write the data
00586       SerialDBKey <KeyOperator_t> key ;
00587       SerialDBData<ValOperator_t> val ;
00588       map< KeyOperator_t, ValOperator_t >::iterator it;
00589       for(it=data.begin();it!=data.end();it++){
00590         key.key()  = it->first  ;
00591         val.data().op.resize(it->second.op.size()) ;
00592         // normalize to number of quarks 
00593         for(int i(0);i<it->second.op.size();i++)
00594           val.data().op[i] = it->second.op[i]/toDouble(quarks.size());
00595         qdp_db.insert(key,val) ;
00596       }
00597 
00598       // Close the namelist output file XMLDAT
00599       pop(xml_out);     // Disco
00600       
00601       snoop.stop();
00602       QDPIO::cout << name << ": total time = "
00603                   << snoop.getTimeInSeconds() 
00604                   << " secs" << endl;
00605       
00606       QDPIO::cout << name << ": ran successfully" << endl;
00607       
00608       END_CODE();
00609     } 
00610   }  // namespace InlineDiscoEnv
00611 }// namespace chroma

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