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