HepMC Reference Documentation

HepMC

IO_HERWIG.cc

Go to the documentation of this file.
00001 
00002 // Matt.Dobbs@Cern.CH, October 2002
00003 // Herwig 6.400 IO class
00005 
00006 #include "HepMC/IO_HERWIG.h"
00007 #include "HepMC/GenEvent.h"
00008 #include <cstdio>       // needed for formatted output using sprintf 
00009 
00010 namespace HepMC {
00011 
00012     IO_HERWIG::IO_HERWIG() : m_trust_mothers_before_daughters(false),
00013                              m_trust_both_mothers_and_daughters(true),
00014                              m_print_inconsistency_errors(true),
00015                              m_no_gaps_in_barcodes(true),
00016                              m_herwig_to_pdg_id(100,0)
00017     {
00018         // These arrays are copied from Lynn Garren's stdhep 5.01.
00019         //   see http://www-pat.fnal.gov/stdhep.html
00020         // Translation from HERWIG particle ID's to PDG particle ID's.
00021         m_herwig_to_pdg_id[1] =1; 
00022         m_herwig_to_pdg_id[2] =2;
00023         m_herwig_to_pdg_id[3] =3;
00024         m_herwig_to_pdg_id[4] =4;
00025         m_herwig_to_pdg_id[5] =5;
00026         m_herwig_to_pdg_id[6] =6;
00027         m_herwig_to_pdg_id[7] =7;
00028         m_herwig_to_pdg_id[8] =8;
00029        
00030         m_herwig_to_pdg_id[11] =11;
00031         m_herwig_to_pdg_id[12] =12;
00032         m_herwig_to_pdg_id[13] =13;
00033         m_herwig_to_pdg_id[14] =14;
00034         m_herwig_to_pdg_id[15] =15;
00035         m_herwig_to_pdg_id[16] =16;
00036        
00037         m_herwig_to_pdg_id[21] =21;
00038         m_herwig_to_pdg_id[22] =22;
00039         m_herwig_to_pdg_id[23] =23;
00040         m_herwig_to_pdg_id[24] =24;
00041         m_herwig_to_pdg_id[25] =25;
00042         m_herwig_to_pdg_id[26] =51; // <--
00043        
00044         m_herwig_to_pdg_id[32] =32;
00045         m_herwig_to_pdg_id[35] =35;
00046         m_herwig_to_pdg_id[36] =36;
00047         m_herwig_to_pdg_id[37] =37;
00048         m_herwig_to_pdg_id[39] =39;
00049  
00050         m_herwig_to_pdg_id[40] =40; //Charybdis Black Hole
00051       
00052         m_herwig_to_pdg_id[81] =81;
00053         m_herwig_to_pdg_id[82] =82;
00054         m_herwig_to_pdg_id[83] =83;
00055         m_herwig_to_pdg_id[84] =84;
00056         m_herwig_to_pdg_id[85] =85;
00057         m_herwig_to_pdg_id[86] =86;
00058         m_herwig_to_pdg_id[87] =87;
00059         m_herwig_to_pdg_id[88] =88;
00060         m_herwig_to_pdg_id[89] =89;
00061         m_herwig_to_pdg_id[90] =90;
00062        
00063         m_herwig_to_pdg_id[91] =91;
00064         m_herwig_to_pdg_id[92] =92;
00065         m_herwig_to_pdg_id[93] =93;
00066         m_herwig_to_pdg_id[94] =94;
00067         m_herwig_to_pdg_id[95] =95;
00068         m_herwig_to_pdg_id[96] =96;
00069         m_herwig_to_pdg_id[97] =97;
00070         m_herwig_to_pdg_id[98] =9920022; // <--
00071         m_herwig_to_pdg_id[99] =9922212; // <--
00072 
00073         // These particle ID's have no antiparticle, so aren't allowed.
00074         m_no_antiparticles.insert(-21);
00075         m_no_antiparticles.insert(-22);
00076         m_no_antiparticles.insert(-23);
00077         m_no_antiparticles.insert(-25);
00078         m_no_antiparticles.insert(-51);
00079         m_no_antiparticles.insert(-35);
00080         m_no_antiparticles.insert(-36);
00081     }
00082 
00083     IO_HERWIG::~IO_HERWIG(){}
00084 
00085     void IO_HERWIG::print( std::ostream& ostr ) const { 
00086         ostr << "IO_HERWIG: reads an event from the FORTRAN Herwig HEPEVT "
00087              << "common block. \n" 
00088              << " trust_mothers_before_daughters = " 
00089              << m_trust_mothers_before_daughters
00090              << " trust_both_mothers_and_daughters = "
00091              << m_trust_both_mothers_and_daughters
00092              << " print_inconsistency_errors = " 
00093              << m_print_inconsistency_errors << std::endl;
00094     }
00095 
00096     bool IO_HERWIG::fill_next_event( GenEvent* evt ) {
00099         //
00100         // 0. Test that evt pointer is not null and set event number
00101         if ( !evt ) {
00102             std::cerr 
00103                 << "IO_HERWIG::fill_next_event error - passed null event." 
00104                 << std::endl;
00105             return 0;
00106         }
00107 
00108         // 1. First we have to fix the HEPEVT input, which is all mucked up for
00109         //    herwig.
00110         repair_hepevt();
00111 
00112         evt->set_event_number( HEPEVT_Wrapper::event_number() );
00113         //
00114         // 2. create a particle instance for each HEPEVT entry and fill a map
00115         //    create a vector which maps from the HEPEVT particle index to the 
00116         //    GenParticle address
00117         //    (+1 in size accounts for hepevt_particle[0] which is unfilled)
00118         std::vector<GenParticle*> hepevt_particle( 
00119                                         HEPEVT_Wrapper::number_entries()+1 );
00120         hepevt_particle[0] = 0;
00121         for ( int i1 = 1; i1 <= HEPEVT_Wrapper::number_entries(); ++i1 ) {
00122             hepevt_particle[i1] = build_particle(i1);
00123         }
00124         std::set<GenVertex*> new_vertices;
00125         //
00126         // Here we assume that the first two particles in the list 
00127         // are the incoming beam particles.
00128         // Best make sure this is done before any rearranging...
00129         evt->set_beam_particles( hepevt_particle[1], hepevt_particle[2] );
00130         //
00131         // 3. We need to take special care with the hard process
00132         // vertex.  The problem we are trying to avoid is when the
00133         // partons entering the hard process also have daughters from
00134         // the parton shower. When this happens, each one can get its
00135         // own decay vertex, making it difficult to join them
00136         // later. We handle it by joining them together first, then
00137         // the other daughters get added on later.
00138         // Find the partons entering the hard vertex (status codes 121, 122).
00139         int index_121 = 0;
00140         int index_122 = 0;
00141         for ( int i = 1; i <=HEPEVT_Wrapper::number_entries(); i++ ) {
00142             if ( HEPEVT_Wrapper::status(i)==121 ) index_121=i;
00143             if ( HEPEVT_Wrapper::status(i)==122 ) index_122=i;
00144             if ( index_121!=0 && index_122!=0 ) break;
00145         }
00146         if ( index_121 && index_122 ) {
00147             GenVertex* hard_vtx = new GenVertex();
00148             hard_vtx->add_particle_in( hepevt_particle[index_121] );
00149             hard_vtx->add_particle_in( hepevt_particle[index_122] );
00150             // evt->add_vertex( hard_vtx ); // not necessary, its done in 
00151                                             // set_signal_process_vertex
00152             //BPK - Atlas -> index_hard retained if it is a boson
00153             int index_hard = 0;
00154             for ( int i = 1; i <=HEPEVT_Wrapper::number_entries(); i++ ) {
00155               if ( HEPEVT_Wrapper::status(i)==120 ) index_hard=i;
00156               if ( index_hard!=0 ) break;
00157             }
00158             
00159             if ( index_hard!=0) {
00160               hard_vtx->add_particle_out( hepevt_particle[index_hard] );
00161               GenVertex* hard_vtx2 = new GenVertex();
00162               hard_vtx2->add_particle_in( hepevt_particle[index_hard] );
00163                   for ( int i = 1; i <= HEPEVT_Wrapper::number_entries(); ++i ) {
00164                 if (  HEPEVT_Wrapper::first_parent(i)==index_hard ) {
00165                   hard_vtx2->add_particle_out( hepevt_particle[i] );
00166                 }
00167               }
00168               evt->set_signal_process_vertex( hard_vtx );
00169               evt->set_signal_process_vertex( hard_vtx2 );
00170             }
00171             else {
00172               evt->set_signal_process_vertex( hard_vtx );
00173             }
00174             //BPK - Atlas -<
00175         }
00176         //
00177         // 4. loop over HEPEVT particles AGAIN, this time creating vertices
00178         for ( int i = 1; i <= HEPEVT_Wrapper::number_entries(); ++i ) {
00179             // We go through and build EITHER the production or decay 
00180             // vertex for each entry in hepevt, depending on the switch
00181             // m_trust_mothers_before_daughters (new 2001-02-28)
00182             // Note: since the HEPEVT pointers are bi-directional, it is
00184             //
00185             // 3. Build the production_vertex (if necessary)
00186             if ( m_trust_mothers_before_daughters || 
00187                  m_trust_both_mothers_and_daughters ) {
00188                 build_production_vertex( i, hepevt_particle, evt );
00189             }
00190             //
00191             // 4. Build the end_vertex (if necessary) 
00192             //    Identical steps as for production vertex
00193             if ( !m_trust_mothers_before_daughters || 
00194                  m_trust_both_mothers_and_daughters ) {
00195                 build_end_vertex( i, hepevt_particle, evt );
00196             }
00197         }
00198         // 5.             01.02.2000
00199         // handle the case of particles in HEPEVT which come from nowhere -
00200         //  i.e. particles without mothers or daughters.
00201         //  These particles need to be attached to a vertex, or else they
00202         //  will never become part of the event. check for this situation.
00203         for ( int i3 = 1; i3 <= HEPEVT_Wrapper::number_entries(); ++i3 ) {
00204             // Herwig also has some non-physical entries in HEPEVT
00205             // like CMS, HARD, and CONE. These are flagged by
00206             // repair_hepevt by making their status and id zero. We
00207             // delete those particles here.
00208             if ( hepevt_particle[i3] && !hepevt_particle[i3]->parent_event()
00209                  && !hepevt_particle[i3]->pdg_id()
00210                  && !hepevt_particle[i3]->status() ) {
00211                 //std::cout << "IO_HERWIG::fill_next_event is deleting null "
00212                 //        << "particle" << std::endl;
00213                 //hepevt_particle[i3]->print();
00214                 delete hepevt_particle[i3];
00215             } else if ( hepevt_particle[i3] && 
00216                         !hepevt_particle[i3]->end_vertex() && 
00217                         !hepevt_particle[i3]->production_vertex() ) {
00218                 GenVertex* prod_vtx = new GenVertex();
00219                 prod_vtx->add_particle_out( hepevt_particle[i3] );
00220                 evt->add_vertex( prod_vtx );
00221             }
00222         }
00223         return true;
00224     }
00225 
00226     void IO_HERWIG::build_production_vertex(int i, 
00227                                             std::vector<GenParticle*>& 
00228                                             hepevt_particle,
00229                                             GenEvent* evt ) {
00233         GenParticle* p = hepevt_particle[i];
00234         // a. search to see if a production vertex already exists
00235         int mother = HEPEVT_Wrapper::first_parent(i);
00236         GenVertex* prod_vtx = p->production_vertex();
00237         while ( !prod_vtx && mother > 0 ) {
00238             prod_vtx = hepevt_particle[mother]->end_vertex();
00239             if ( prod_vtx ) prod_vtx->add_particle_out( p );
00240             // increment mother for next iteration
00241             if ( ++mother > HEPEVT_Wrapper::last_parent(i) ) mother = 0;
00242         }
00243         // b. if no suitable production vertex exists - and the particle
00244         // has atleast one mother or position information to store - 
00245         // make one
00246         FourVector prod_pos( HEPEVT_Wrapper::x(i), HEPEVT_Wrapper::y(i), 
00247                                    HEPEVT_Wrapper::z(i), HEPEVT_Wrapper::t(i) 
00248                                  ); 
00249         if ( !prod_vtx && (HEPEVT_Wrapper::number_parents(i)>0 
00250                            || prod_pos!=FourVector(0,0,0,0)) )
00251         {
00252             prod_vtx = new GenVertex();
00253             prod_vtx->add_particle_out( p );
00254             evt->add_vertex( prod_vtx ); 
00255         }
00256         // c. if prod_vtx doesn't already have position specified, fill it
00257         if ( prod_vtx && prod_vtx->position()==FourVector(0,0,0,0) ) {
00258             prod_vtx->set_position( prod_pos );
00259         }
00260         // d. loop over mothers to make sure their end_vertices are
00261         //     consistent
00262         mother = HEPEVT_Wrapper::first_parent(i);
00263         while ( prod_vtx && mother > 0 ) {
00264             if ( !hepevt_particle[mother]->end_vertex() ) {
00265                 // if end vertex of the mother isn't specified, do it now
00266                 prod_vtx->add_particle_in( hepevt_particle[mother] );
00267             } else if (hepevt_particle[mother]->end_vertex() != prod_vtx ) {
00268                 // problem scenario --- the mother already has a decay
00269                 // vertex which differs from the daughter's produciton 
00270                 // vertex. This means there is internal
00271                 // inconsistency in the HEPEVT event record. Print an
00272                 // error
00273                 // Note: we could provide a fix by joining the two 
00274                 //       vertices with a dummy particle if the problem
00275                 //       arrises often with any particular generator.
00276                 if ( m_print_inconsistency_errors ) {
00277                   std::cerr
00278                     << "HepMC::IO_HERWIG: inconsistent mother/daugher "
00279                     << "information in HEPEVT event " 
00280                     << HEPEVT_Wrapper::event_number()
00281                     << ". \n I recommend you try "
00282                     << "inspecting the event first with "
00283                     << "\n\tHEPEVT_Wrapper::check_hepevt_consistency()"
00284                     << "\n This warning can be turned off with the "
00285                     << "IO_HERWIG::print_inconsistency_errors switch."
00286                     << std::endl;
00287                   hepevt_particle[mother]->print(std::cerr);
00288                   std::cerr
00289                     << "problem vertices are: (prod_vtx, mother)" << std::endl;
00290                   if ( prod_vtx ) prod_vtx->print(std::cerr);
00291                   hepevt_particle[mother]->end_vertex()->print(std::cerr);
00292                 }
00293             }
00294             if ( ++mother > HEPEVT_Wrapper::last_parent(i) ) mother = 0;
00295         }
00296     }
00297 
00298     void IO_HERWIG::build_end_vertex
00299     ( int i, std::vector<GenParticle*>& hepevt_particle, GenEvent* evt ) 
00300     {
00304         //    Identical steps as for build_production_vertex
00305         GenParticle* p = hepevt_particle[i];
00306         // a.
00307         int daughter = HEPEVT_Wrapper::first_child(i);
00308         GenVertex* end_vtx = p->end_vertex();
00309         while ( !end_vtx && daughter > 0 ) {
00310             end_vtx = hepevt_particle[daughter]->production_vertex();
00311             if ( end_vtx ) end_vtx->add_particle_in( p );
00312             if ( ++daughter > HEPEVT_Wrapper::last_child(i) ) daughter = 0;
00313         }
00314         // b. (different from 3c. because HEPEVT particle can not know its
00315         //        decay position )
00316         if ( !end_vtx && HEPEVT_Wrapper::number_children(i)>0 ) {
00317             end_vtx = new GenVertex();
00318             end_vtx->add_particle_in( p );
00319             evt->add_vertex( end_vtx );
00320         }
00321         // c+d. loop over daughters to make sure their production vertices 
00322         //    point back to the current vertex.
00323         //    We get the vertex position from the daughter as well.
00324         daughter = HEPEVT_Wrapper::first_child(i);
00325         while ( end_vtx && daughter > 0 ) {
00326             if ( !hepevt_particle[daughter]->production_vertex() ) {
00327                 // if end vertex of the mother isn't specified, do it now
00328                 end_vtx->add_particle_out( hepevt_particle[daughter] );
00329                 // 
00330                 // 2001-03-29 M.Dobbs, fill vertex the position.
00331                 if ( end_vtx->position()==FourVector(0,0,0,0) ) {
00332                     FourVector prod_pos( HEPEVT_Wrapper::x(daughter), 
00333                                                HEPEVT_Wrapper::y(daughter), 
00334                                                HEPEVT_Wrapper::z(daughter), 
00335                                                HEPEVT_Wrapper::t(daughter) 
00336                         );
00337                     if ( prod_pos != FourVector(0,0,0,0) ) {
00338                         end_vtx->set_position( prod_pos );
00339                     }
00340                 }
00341             } else if (hepevt_particle[daughter]->production_vertex() 
00342                        != end_vtx){
00343                 // problem scenario --- the daughter already has a prod
00344                 // vertex which differs from the mother's end 
00345                 // vertex. This means there is internal
00346                 // inconsistency in the HEPEVT event record. Print an
00347                 // error
00348                 if ( m_print_inconsistency_errors ) std::cerr
00349                     << "HepMC::IO_HERWIG: inconsistent mother/daugher "
00350                     << "information in HEPEVT event " 
00351                     << HEPEVT_Wrapper::event_number()
00352                     << ". \n I recommend you try "
00353                     << "inspecting the event first with "
00354                     << "\n\tHEPEVT_Wrapper::check_hepevt_consistency()"
00355                     << "\n This warning can be turned off with the "
00356                     << "IO_HERWIG::print_inconsistency_errors switch."
00357                     << std::endl;
00358             }
00359             if ( ++daughter > HEPEVT_Wrapper::last_child(i) ) daughter = 0;
00360         }
00361         if ( !p->end_vertex() && !p->production_vertex() ) {
00362             // Added 2001-11-04, to try and handle Isajet problems.
00363             build_production_vertex( i, hepevt_particle, evt );
00364         }
00365     }
00366 
00367     GenParticle* IO_HERWIG::build_particle( int index ) {
00369         // 
00370         GenParticle* p 
00371             = new GenParticle( FourVector( HEPEVT_Wrapper::px(index), 
00372                                                  HEPEVT_Wrapper::py(index), 
00373                                                  HEPEVT_Wrapper::pz(index), 
00374                                                  HEPEVT_Wrapper::e(index) ),
00375                                HEPEVT_Wrapper::id(index), 
00376                                HEPEVT_Wrapper::status(index) );
00377         p->setGeneratedMass( HEPEVT_Wrapper::m(index) );
00378         p->suggest_barcode( index );
00379         return p;
00380     }
00381 
00382     int IO_HERWIG::find_in_map( const std::map<GenParticle*,int>& m, 
00383                                 GenParticle* p) const {
00384         std::map<GenParticle*,int>::const_iterator iter = m.find(p);
00385         if ( iter == m.end() ) return 0;
00386         return iter->second;
00387     }
00388 
00389     void IO_HERWIG::repair_hepevt() const {
00412 
00413         // Make sure hepvt isn't empty.
00414         if ( HEPEVT_Wrapper::number_entries() <= 0 ) return;
00415 
00416         // Find the index of the beam-beam collision and of the hard subprocess
00417         // Later we will assume that 
00418         //              101 ---> 121 \. 
00419         //                             X  Hard subprocess
00420         //              102 ---> 122 /
00421         // 
00422         int index_collision = 0;
00423         int index_hard = 0;
00424         int index_101 = 0;
00425         int index_102 = 0;
00426         int index_121 = 0;
00427         int index_122 = 0;
00428 
00429         for ( int i = 1; i <=HEPEVT_Wrapper::number_entries(); i++ ) {
00430             if ( HEPEVT_Wrapper::status(i)==101 ) index_101=i;
00431             if ( HEPEVT_Wrapper::status(i)==102 ) index_102=i;
00432             if ( HEPEVT_Wrapper::status(i)==103 ) index_collision=i;
00433             if ( HEPEVT_Wrapper::status(i)==120 ) index_hard=i;
00434             if ( HEPEVT_Wrapper::status(i)==121 ) index_121=i;
00435             if ( HEPEVT_Wrapper::status(i)==122 ) index_122=i;
00436             if ( index_collision!=0 && index_hard!=0 && index_101!=0 && 
00437                  index_102!=0 && index_121!=0 && index_122!=0 ) break;
00438         }
00439 
00440         // The mother daughter information for the hard subprocess entry (120)
00441         // IS correct, whereas the information for the particles participating
00442         // in the hard subprocess contains instead the color flow relationships
00443         // Transfer the hard subprocess info onto the other particles
00444         // in the hard subprocess.
00445         //
00446         // We cannot specify daughters of the incoming hard process particles
00447         // because they have some daughters (their showered versions) which 
00448         // are not adjacent in the particle record, so we cannot properly 
00449         // set the daughter indices in hepevt.
00450         //
00451         if (index_121) HEPEVT_Wrapper::set_parents(index_121, index_101, 0 );
00452         if (index_121) HEPEVT_Wrapper::set_children( index_121, 0, 0 );
00453         if (index_122) HEPEVT_Wrapper::set_parents(index_122, index_102, 0 );
00454         if (index_122) HEPEVT_Wrapper::set_children( index_122, 0, 0 );
00455 
00456         for ( int i = HEPEVT_Wrapper::first_child(index_hard);
00457               i <= HEPEVT_Wrapper::last_child(index_hard); i++ ) {
00458             //BPK - Atlas ->
00459             if (index_hard && HEPEVT_Wrapper::id(index_hard) == 0 ) {
00460               HEPEVT_Wrapper::set_parents( 
00461                   i, HEPEVT_Wrapper::first_parent(index_hard), 
00462                   HEPEVT_Wrapper::last_parent(index_hard) );
00463             //BPK -> inconsistency in HWHGUP, desc from hard vert should point to it.
00464             } else if (  HEPEVT_Wrapper::first_parent(i)!=index_hard) {
00465               HEPEVT_Wrapper::set_parents(i,index_hard,HEPEVT_Wrapper::last_parent(i) );
00466             }
00467             //BPK - Atlas -<
00468 
00469             // When the direct descendants of the hard process are hadrons,
00470             // then the 2nd child contains color flow information, and so
00471             // we zero it.
00472             // However, if the direct descendant is status=195, then it is
00473             // a non-hadron, and so the 2nd child does contain real mother
00474             // daughter relationships. ( particularly relevant for H->WW,
00475             //                           April 18, 2003 )
00476             // BPK - part of the inconsistency in HWHGUP problem
00477             if ( HEPEVT_Wrapper::status(i) != 195 && HEPEVT_Wrapper::status(i) != 155 ) {             
00478               HEPEVT_Wrapper::set_children(i,HEPEVT_Wrapper::first_child(i),0);
00479             }
00480         }
00481 
00482         // now zero the collision and hard entries.
00483         //BPK - Atlas ->
00484         if (index_hard && HEPEVT_Wrapper::id(index_hard) == 0 ) zero_hepevt_entry(index_hard);
00485         if (index_hard && HEPEVT_Wrapper::id(index_collision) == 0  ) zero_hepevt_entry(index_collision);
00486         //BPK - Atlas -<
00487 
00488         //     Loop over the particles individually and handle oddities
00489         for ( int i=1; i <=HEPEVT_Wrapper::number_entries(); i++ ) {
00490 
00491             //       ----------- Fix ID codes ----------
00492             //       particles with ID=94 are mirror images of their mothers:
00493             if ( HEPEVT_Wrapper::id(i)==94 ) {
00494                 HEPEVT_Wrapper::set_id( 
00495                     i, HEPEVT_Wrapper::id( HEPEVT_Wrapper::first_parent(i) ) );
00496             }
00497 
00498             //     ----------- fix STATUS codes ------
00499             //     status=100 particles are "cones" which carry only color info
00500             //     throw them away
00501             if ( HEPEVT_Wrapper::status(i)==100 ) zero_hepevt_entry(i);
00502 
00503 
00504             // NOTE: status 101,102 particles are the beam particles.
00505             //       status 121,129 particles are the hard subprocess particles
00506             // we choose to allow the herwig particles to have herwig
00507             // specific codes, and so we don't bother to change these
00508             // to status =3.
00509 
00510 
00511 
00512 
00513             //  ----------- fix some MOTHER/DAUGHTER relationships
00514             //  Whenever the mother points to the hard process, it is referring
00515             //  to a color flow, so we zero it.
00516             if ( HEPEVT_Wrapper::last_parent(i)==index_hard ) {
00517                 HEPEVT_Wrapper::set_parents( 
00518                     i, HEPEVT_Wrapper::first_parent(i), 0 );
00519             }
00520 
00521             // It makes no sense to have a mother that is younger than you are!
00522 
00523             if ( HEPEVT_Wrapper::first_parent(i) >= i ) {
00524                 HEPEVT_Wrapper::set_parents( i, 0, 0 );
00525             }
00526             if ( HEPEVT_Wrapper::last_parent(i) >= i ) {
00527                 HEPEVT_Wrapper::set_parents( 
00528                     i, HEPEVT_Wrapper::first_parent(i), 0 );
00529             }
00530 
00531             // Whenever the second mother/daughter has a lower index than the
00532             // first, it means the second mother/daughter contains color
00533             // info. Purge it.
00534             if ( HEPEVT_Wrapper::last_parent(i) <= 
00535                  HEPEVT_Wrapper::first_parent(i) ) {
00536                 HEPEVT_Wrapper::set_parents( 
00537                     i, HEPEVT_Wrapper::first_parent(i), 0 );
00538             }
00539 
00540             if ( HEPEVT_Wrapper::last_child(i) <= 
00541                  HEPEVT_Wrapper::first_child(i) ) {
00542                 HEPEVT_Wrapper::set_children(
00543                     i, HEPEVT_Wrapper::first_child(i), 0 );
00544             }
00545 
00546             // The mothers & daughters of a soft centre of mass (stat=170) seem
00547             // to be correct, but they are out of sequence. The information is
00548             // elsewhere in the event record, so zero it.
00549             //
00550             if ( HEPEVT_Wrapper::status(i) == 170 ) {
00551                 HEPEVT_Wrapper::set_parents( i, 0, 0 );
00552                 HEPEVT_Wrapper::set_children( i, 0, 0 );
00553             }
00554 
00555             // Recognise clusters.
00556             // Case 1: cluster has particle parents.  
00557             // Clusters normally DO point to its two
00558             // correct mothers, but those 2 mothers are rarely adjacent in the
00559             // event record ... so the mother information might say something
00560             // like 123,48 where index123 and index48 really are the correct
00561             // mothers... however the hepevt standard states that the mother
00562             // pointers should give the index range. So we would have to
00563             // reorder the event record and add entries if we wanted to use
00564             // it. Instead we just zero the mothers, since all of that
00565             // information is contained in the daughter information of the
00566             // mothers.
00567             // Case 2: cluster has a soft process centre of mass (stat=170)
00568             // as parent. This is ok, keep it.
00569             //
00570             // Note if we were going directly to HepMC, then we could 
00571             //  use this information properly!
00572 
00573             if ( HEPEVT_Wrapper::id(i)==91 ) {
00574                 // if the cluster comes from a SOFT (id=0,stat=170)
00575                 if ( HEPEVT_Wrapper::status(HEPEVT_Wrapper::first_parent(i)) 
00576                      == 170 ) {
00577                     ; // In this case the mothers are ok
00578                 } else {
00579                     HEPEVT_Wrapper::set_parents( i, 0, 0 );
00580                 }
00581             }
00582         }
00583         
00584         //     ---------- Loop over the particles individually and look 
00585         //                for mother/daughter inconsistencies.
00586         // We consider a mother daughter relationship to be valid
00587         // ONLy when the mother points to the daughter AND the
00588         // daughter points back (true valid bidirectional
00589         // pointers) OR when a one thing points to the other, but
00590         // the other points to zero. If this isn't true, we zero
00591         // the offending relationship.
00592 
00593         for ( int i=1; i <=HEPEVT_Wrapper::number_entries(); i++ ) {
00594             // loop over parents
00595             int ifirst = HEPEVT_Wrapper::first_parent(i);
00596             int ilast = HEPEVT_Wrapper::last_parent(i);
00597             if ( ilast == 0 ) ilast = HEPEVT_Wrapper::first_parent(i);
00598             bool first_is_acceptable = true;
00599             bool last_is_acceptable = true;
00600             // check for out of range.
00601             if ( ifirst>=i || ifirst<0 ) first_is_acceptable = false;
00602             if ( ilast>=i || ilast<ifirst || ilast<0 )last_is_acceptable=false;
00603             if ( first_is_acceptable ) {
00604                 for ( int j = ifirst; j<=ilast; j++ ) {
00605                     // these are the acceptable outcomes
00606                     if ( HEPEVT_Wrapper::first_child(j)==i ) {;} 
00607                     // watch out
00608                     else if ( HEPEVT_Wrapper::first_child(j) <=i && 
00609                               HEPEVT_Wrapper::last_child(j) >=i ) {;}
00610                     else if ( HEPEVT_Wrapper::first_child(j) ==0 && 
00611                               HEPEVT_Wrapper::last_child(j) ==0 ) {;}
00612 
00613                     // Error Condition:
00614                     // modified by MADobbs@lbl.gov April 21, 2003
00615                     // we distinguish between the first parent and all parents
00616                     //  being incorrect
00617                     else if (j==ifirst) { first_is_acceptable = false; break; }
00618                     else { last_is_acceptable = false; break; }
00619                 }
00620             }
00621             // if any one of the mothers gave a bad outcome, zero all mothers
00622             //BPK - Atlas ->
00623             // do not disconnect photons (most probably from photos)
00624             if ( HEPEVT_Wrapper::id(i) == 22 && HEPEVT_Wrapper::status(i) == 1 )
00625               { first_is_acceptable = true; }
00626             //BPK - Atlas -<
00627             if ( !first_is_acceptable ) {
00628               HEPEVT_Wrapper::set_parents( i, 0, 0 );
00629             } else if ( !last_is_acceptable ) {
00630               HEPEVT_Wrapper::set_parents(i,HEPEVT_Wrapper::first_parent(i),0);
00631             }
00632         }
00633         // Note: it's important to finish the mother loop, before
00634         // starting the daughter loop ... since many mother relations
00635         // will be zero'd which will validate the daughters.... i.e.,
00636         // we want relationships like:
00637         //      IHEP    ID      IDPDG IST MO1 MO2 DA1 DA2
00638         //        27 TQRK           6   3  26  26  30  30
00639         //        30 TQRK           6 155  26  11  31  32
00640         // to come out right.
00641 
00642         for ( int i=1; i <=HEPEVT_Wrapper::number_entries(); i++ ) {
00643             // loop over daughters
00644             int ifirst = HEPEVT_Wrapper::first_child(i);
00645             int ilast = HEPEVT_Wrapper::last_child(i);
00646             if ( ilast==0 ) ilast = HEPEVT_Wrapper::first_child(i);
00647             bool is_acceptable = true;
00648             // check for out of range.
00649             if ( ifirst<=i || ifirst<0 ) is_acceptable = false;
00650             if ( ilast<=i || ilast<ifirst || ilast<0 ) is_acceptable = false;
00651             if ( is_acceptable ) {
00652                 for ( int j = ifirst; j<=ilast; j++ ) {
00653                     // these are the acceptable outcomes
00654                     if ( HEPEVT_Wrapper::first_parent(j)==i ) {;} 
00655                     else if ( HEPEVT_Wrapper::first_parent(j) <=i && 
00656                               HEPEVT_Wrapper::last_parent(j) >=i ) {;}
00657                     else if ( HEPEVT_Wrapper::first_parent(j) ==0 && 
00658                               HEPEVT_Wrapper::last_parent(j) ==0 ) {;}
00659                     else { is_acceptable = false; } // error condition 
00660                 }
00661             }
00662             // if any one of the children gave a bad outcome, zero all children
00663             if ( !is_acceptable ) HEPEVT_Wrapper::set_children( i, 0, 0 );
00664         }
00665 
00666         // fixme
00667 
00668         for ( int i=1; i <=HEPEVT_Wrapper::number_entries(); i++ ) {
00669             HEPEVT_Wrapper::set_id(
00670                 i, translate_herwig_to_pdg_id(HEPEVT_Wrapper::id(i)) );
00671         }
00672 
00673 
00674         if ( m_no_gaps_in_barcodes ) remove_gaps_in_hepevt();
00675     }
00676 
00677     void IO_HERWIG::remove_gaps_in_hepevt() const {
00683         std::vector<int> mymap(HEPEVT_Wrapper::number_entries()+1,0);
00684         int ilast = 0;
00685         for ( int i=1; i <=HEPEVT_Wrapper::number_entries(); i++ ) {
00686             if (HEPEVT_Wrapper::status(i)==0 && HEPEVT_Wrapper::id(i)==0) {
00687                 // we remove all entries for which stat=0, id=0
00688                 mymap[i]=0;
00689             } else {
00690                 ilast += 1;
00691                 if ( ilast != i ) {
00692                     HEPEVT_Wrapper::set_status(ilast, 
00693                                                HEPEVT_Wrapper::status(i) );
00694                     HEPEVT_Wrapper::set_id(ilast, HEPEVT_Wrapper::id(i) );
00695                     HEPEVT_Wrapper::set_parents(
00696                         ilast, 
00697                         HEPEVT_Wrapper::first_parent(i),
00698                         HEPEVT_Wrapper::last_parent(i) );
00699                     HEPEVT_Wrapper::set_children(
00700                         ilast, 
00701                         HEPEVT_Wrapper::first_child(i),
00702                         HEPEVT_Wrapper::last_child(i) );
00703                     HEPEVT_Wrapper::set_momentum(
00704                         ilast, 
00705                         HEPEVT_Wrapper::px(i), HEPEVT_Wrapper::py(i),
00706                         HEPEVT_Wrapper::pz(i), HEPEVT_Wrapper::e(i)  );
00707                     HEPEVT_Wrapper::set_mass(ilast, HEPEVT_Wrapper::m(i) );
00708                     HEPEVT_Wrapper::set_position(
00709                         ilast, HEPEVT_Wrapper::x(i),HEPEVT_Wrapper::y(i),
00710                         HEPEVT_Wrapper::z(i),HEPEVT_Wrapper::t(i) );
00711                 }
00712                 mymap[i]=ilast;
00713             }
00714         }
00715 
00716         // M. Dobbs (from Borut) - April 26, to fix tauolo/herwig past
00717         // the end problem with daughter pointers: 
00718         // HEPEVT_Wrapper::set_number_entries( ilast );
00719 
00720         // Finally we need to re-map the mother/daughter pointers.      
00721         for ( int i=1; i <=ilast; i++ ) {
00722 
00723             HEPEVT_Wrapper::set_parents(
00724                 i, 
00725                 mymap[HEPEVT_Wrapper::first_parent(i)],
00726                 mymap[HEPEVT_Wrapper::last_parent(i)] );
00727             HEPEVT_Wrapper::set_children(
00728                 i, 
00729                 mymap[HEPEVT_Wrapper::first_child(i)],
00730                 mymap[HEPEVT_Wrapper::last_child(i)] );
00731         }
00732         // M. Dobbs (from Borut, part B) - April 26, to fix tauolo/herwig past
00733         // the end problem with daughter pointers: 
00734         HEPEVT_Wrapper::set_number_entries( ilast );
00735     }
00736 
00737     void IO_HERWIG::zero_hepevt_entry( int i ) const {
00738       if ( i <=0 || i > HepMC::HEPEVT_Wrapper::max_number_entries() ) return;
00739       HEPEVT_Wrapper::set_status( i, 0 );
00740       HEPEVT_Wrapper::set_id( i, 0 );
00741       HEPEVT_Wrapper::set_parents( i, 0, 0 );
00742       HEPEVT_Wrapper::set_children( i, 0, 0 );
00743       HEPEVT_Wrapper::set_momentum( i, 0, 0, 0, 0 );
00744       HEPEVT_Wrapper::set_mass( i, 0 );
00745       HEPEVT_Wrapper::set_position( i, 0, 0, 0, 0 );
00746     }
00747 
00748     int IO_HERWIG::translate_herwig_to_pdg_id( int id ) const {
00751  
00752                                                // example -9922212
00753         int hwtran = id;                       //         -9922212
00754         int ida    = abs(id);                  //          9922212
00755         int j1     = ida%10;                   //                2
00756         int i1     = (ida/10)%10;              //               1
00757         int i2     = (ida/100)%10;             //              2
00758         int i3     = (ida/1000)%10;            //             2
00759         //int i4     =(ida/10000)%10;          //            2
00760         //int i5     =(ida/100000)%10;         //           9
00761         //int k99    = (ida/100000)%100;       //          9
00762         int ksusy  = (ida/1000000)%10;         //         0
00763         //int ku     = (ida/10000000)%10;      //        0
00764         int kqn    = (ida/1000000000)%10;      //       0
00765 
00766         if ( kqn==1 ) {
00767             //  ions not recognized
00768             hwtran=0;
00769             if ( m_print_inconsistency_errors ) {
00770                 std::cerr << "IO_HERWIG::translate_herwig_to_pdg_id " << id
00771                           << "nonallowed ion" << std::endl;
00772             }
00773         } 
00774         else if (ida < 100) {
00775             // Higgs, etc.
00776             hwtran = m_herwig_to_pdg_id[ida];
00777             if ( id < 0 ) hwtran *= -1;
00778             // check for illegal antiparticles
00779             if ( id < 0 ) {
00780                 if ( hwtran>=-99 && hwtran<=-81) hwtran=0;
00781                 if ( m_no_antiparticles.count(hwtran) ) hwtran=0;
00782             }
00783         }
00784         else if ( ksusy==1 || ksusy==2 ) { ; }
00785         //  SUSY
00786         else if ( i1!=0 && i3!=0 && j1==2 ) {;}
00787         // spin 1/2 baryons
00788         else if ( i1!=0 && i3!=0 && j1==4 ) {;}
00789         // spin 3/2 baryons
00790         else if ( i1!=0 && i2!=0 && i3==0 ) {
00791             // mesons 
00792             // check for illegal antiparticles
00793             if ( i1==i2 && id<0) hwtran=0;
00794         } 
00795         else if ( i2!=0 && i3!=0 && i1==0 ) {;}
00796         // diquarks
00797         else {
00798             // undefined
00799             hwtran=0;
00800         }
00801 
00802         // check for illegal anti KS, KL
00803         if ( id==-130 || id==-310 ) hwtran=0;
00804 
00805         if ( hwtran==0 && ida!=0 && m_print_inconsistency_errors ) {
00806             std::cerr 
00807                 << "IO_HERWIG::translate_herwig_to_pdg_id HERWIG particle " 
00808                 << id << " translates to zero." << std::endl;
00809         }
00810 
00811         return hwtran;
00812     }
00813 
00814 } // HepMC
00815 
00816 
00817 
00818 

Generated on Wed Jun 3 13:42:28 2009 for HepMC by  doxygen 1.5.1-3