Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F8309542
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
39 KB
Subscribers
None
View Options
diff --git a/MatrixElement/Matchbox/ColorFull/Col_str.cc b/MatrixElement/Matchbox/ColorFull/Col_str.cc
--- a/MatrixElement/Matchbox/ColorFull/Col_str.cc
+++ b/MatrixElement/Matchbox/ColorFull/Col_str.cc
@@ -1,976 +1,974 @@
// -*- C++ -*-
/*
* Col_str.cc
* Contains definition of the class Col_str and associated types and operators.
* Created on: Jul 7, 2010
* Author: Malin Sjodahl
*/
#include "Col_str.h"
#include <cassert>
#include <fstream>
#include <iostream>
namespace ColorFull {
Col_str::Col_str( const std::string str ) {
Col_str_of_str( str );
}
void Col_str::Col_str_of_str( const std::string str ) {
// First split the string into Col_str and Polynomial part
uint j=0;
// Check that left and right normal brackets match up
j=0;
int left_brackets=0,right_brackets=0;
while (j < str.size()) {
if(str.at(j)=='(') left_brackets++;
if(str.at(j)==')') right_brackets++;
j++;
}
if(left_brackets != right_brackets){
std::cerr << "Col_str::Col_str_of_str: The normal brackets, (), in the Col_str\"" << str <<"\" do not seem to match up. There were "
<< left_brackets <<" left bracket(s) and "<< right_brackets << " right bracket(s)." << std::endl;
assert( 0 );
}
// Check that left and right curly brackets match up
left_brackets=0,right_brackets=0;
j=0;
while (j < str.size()) {
if(str.at(j)=='{') left_brackets++;
if(str.at(j)=='}') right_brackets++;
j++;
}
if(left_brackets != right_brackets){
std::cerr << "Col_str::Col_str_of_str: The curly brackets in the Col_str\"" << str <<"\" do not seem to match up. There were "
<< left_brackets <<" left bracket(s) and "<< right_brackets << " right bracket(s)." << std::endl;
assert( 0 );
}
// Check that left and right [] brackets match up
j=0;
left_brackets=0, right_brackets=0;
while (j < str.size()) {
if(str.at(j)=='[') left_brackets++;
if(str.at(j)==']') right_brackets++;
j++;
}
if(left_brackets != right_brackets){
std::cerr << "Col_str::Col_str_of_str: The square brackets, [], in the string \"" << str <<"\" do not seem to match up. There were "
<< left_brackets <<" left bracket(s) and "<< right_brackets << " right bracket(s)." << std::endl;
assert( 0 );
}
if( left_brackets != 1){
std::cerr << "Col_str::Col_str_of_str: Found " << left_brackets << " squared, [], left brackets in the string " << str
<<" but there should be 1;" << std::endl;
assert( 0 );
}
// Read in the Polynomial until a [ is found
j=0;
- std::string Poly_string;
- Poly_string.empty();
+ std::string Poly_string;
while( j<str.size() and str.at(j)!='['){
Poly_string.push_back(str.at(j));
j++;
}
// Then read in the col_str
std::string col_string;
- col_string.empty();
while( j< str.size() and str.at(j)!=']'){
col_string.push_back( str.at(j) );
j++;
}
// Get the final ], In this way the final sign will be ]
col_string.push_back( str.at(j) );
Poly=Polynomial( Poly_string );
col_str_of_str( col_string );
}
void Col_str::col_str_of_str(std::string str) {
// First sign should be '['
if (str.at(0) != '[') {
std::cerr
<< "Col_str::col_str_of_str: First char in col_str should be '[', it was: "
<< str.at(0) << std::endl;
std::cerr.flush();
assert( 0 );
}
uint i = 0; // set i to 0 to start at position 1 after adding 1
while (i < str.size() - 2) {
// To contain the argument to the Quark_line constructor
std::string Ql_arg;
Ql_arg.clear();
// Increase i with 1, to compensate for ')'
i += 1;
// Make argument to the Quark_line constructor
// Keep reading while not ')' or '}'
while (str.at(i) != ')' && str.at(i) != '}') {
Ql_arg.push_back(str.at(i));
i++;
//cout << "Col_str::Col_str(str): For " << i << " The str is: " << Ql_arg << std::endl;
}
// Append last char ')' or '}'
Ql_arg.push_back(str.at(i));
Quark_line Ql(Ql_arg);
cs.push_back(Ql_arg);
}
// Last sign should be ']'
if (str.at(str.size() - 1) != ']') {
std::cerr
<< "Col_str::col_str_of_str: Last char in col_str should be ']', it was: "
<< str.at(str.size() - 1) << std::endl;
std::cerr.flush();
assert( 0 );
}
}
void Col_str::read_in_Col_str( std::string filename ) {
// Read in file
std::ifstream fin(filename.c_str() );
// Check that file exists
if( !fin ){
std::cerr << "Col_str::read_in_Col_str: The file "
<< filename << " could not be opened." << std::endl;
assert( 0 );
}
// Copy info from file to string
std::string str((std::istreambuf_iterator<char>(fin)), std::istreambuf_iterator<char>());
// Skip lines starting with #
while( str.at(0)== '#' ){
while (str.at(0) != '\n'){
str.erase(str.begin());
}
// erase endl sign(s)
while(str.at(0)== '\n'){
str.erase(str.begin());
}
}
// Remove endl chars at the end of the file
while( str.at(str.size()-1) == '\n' ) str.erase(str.size()-1);
Col_str_of_str( str );
}
void Col_str::write_out_Col_str( std::string filename ) const {
if ((cs.size() == 0)) {
std::cout
<< "Col_str::write_out_Col_str: The Col_str is empty."
<< std::endl;
std::cout.flush();
return;
}
std::ofstream outfile(filename.c_str());
if ( !outfile )
std::cerr << "Col_str::write_out_Col_str: Cannot write out Col_str as the file \""
<< filename.c_str() << "\" could not be opened. (Does the directory exist? Consider creating the directory.)" << std::endl;
outfile << *this;
}
int Col_str::at( int i, int j ) const {
if (i < 0) {
std::cout << "Col_str::at: First argument <0\n";
std::cerr.flush();
assert( 0 );
} else if (i >= static_cast<int>(cs.size()) ) {
std::cerr << "Col_str::at: First argument > size -1\n";
std::cerr.flush();
assert( 0 );
}
if (j < 0) {
std::cerr << "Col_str::at: Second argument <0 \n";
std::cerr.flush();
assert( 0 );
} else if (j >= static_cast<int>(cs.at(i).ql.size())) {
std::cerr << "Col_str::at: Second argument > size -1\n";
std::cerr.flush();
assert( 0 );
}
return cs.at(i).ql.at(j);
}
void Col_str::erase( int i ) {
cs.erase(cs.begin() + i);
}
void Col_str::erase( int i, int j ) {
cs.at(i).ql.erase(cs.at(i).ql.begin() + j);
}
void Col_str::erase( std::pair<int, int> place ) {
erase(place.first, place.second);
}
void Col_str::insert( int i, int j, int part_num ) {
// Checking that location is within range
if (i < 0) {
std::cerr << "Col_str::insert: First argument <0\n";
std::cerr.flush();
assert( 0 );
} else if (i >= static_cast<int> (cs.size()) ) {
std::cerr << "Col_str::insert: First argument > size -1\n";
std::cerr.flush();
assert( 0 );
}
if (j < 0) {
std::cerr << "Col_str::insert: Second argument <0\n";
std::cerr.flush();
assert( 0 );
} else if (j > static_cast<int>( cs.at(i).ql.size()) ) {
std::cerr << "Col_str::insert: Second argument > size, was " << j << std::endl;
std::cerr.flush();
assert( 0 );
}
// Inserting element at place given by iterator itj
quark_line::iterator itj = cs.at(i).ql.begin() + j;
cs.at(i).ql.insert(itj, part_num);
}
void Col_str::append( col_str cs_in ) {
for (uint j = 0; j < cs_in.size(); j++) {
cs.push_back(cs_in.at(j));
}
}
std::pair<int, int> Col_str::find_parton( int part_num ) const {
// Loop over all Quark_lines
for (uint i = 0; i < cs.size(); i++) {
// Loop over all places in the Quark_lines
for (uint j = 0; j < cs.at(i).ql.size(); j++) {
if (cs.at(i).ql.at(j) == part_num) {
// cout << j<< "\n";
return std::make_pair(i, j);
}
}
}
// Assert parton found
std::cerr
<< "Col_str::find_parton: The function find_parton did not find the parton "
<< part_num << "in \n" << cs;
std::cerr.flush();
assert( 0 );
return std::make_pair(-1, -1);
}
bool Col_str::neighbor(int p1,int p2) const{
// The places
std::pair<int, int> place1 = find_parton(p1);
std::pair<int, int> place2 = find_parton(p2);
// First make sure the partons are in the same Quark_line
if( place1.first!=place2.first ) return false;
if( place2.second==place1.second + 1 or place2.second==place1.second - 1) return true;
return false;
}
bool Col_str::right_neighbor(int p1,int p2) const{
return left_neighbor(p2,p1);
}
bool Col_str::left_neighbor(int p1,int p2) const{
// The places
std::pair<int, int> place1 = find_parton(p1);
std::pair<int, int> place2 = find_parton(p2);
// First make sure the partons are in the same Quark_line
if( place1.first!=place2.first ) return false;
bool closed = !at(place1.first).open;
int length = at(place1.first).size();
if ( !(place1.second-place2.second == 1 ||
(place1.second-place2.second == 1 - length && closed)) ) return false;
return true;
}
void Col_str::replace(int old_ind, int new_ind) {
// First, locate the index to replace
std::pair<int, int> place = find_parton(old_ind);
// Then erase the index at that place
erase(place.first, place.second);
// Then insert the new index
insert(place.first, place.second, new_ind);
}
std::string Col_str::find_kind( int p ) const {
// Locate the parton in the Col_str
std::pair<int, int> place = find_parton(p);
// Check if the quark-line is closed
// If the parton is in a closed quark line it's a g
if (!at(place.first).open) {
return "g";
}
// If the parton is first in an open quark-line it's a q
// (the first relevant place is place 1)
else if (place.second == 0) {
return "q";
}
// If the parton is last in an open quark-line it's a qbar
// To find location, subtract the number of characters it takes to write part_num
else if (place.second == static_cast<int> (cs.at(place.first).ql.size()) - 1) {
return "qbar";
}
// add warning if not found?
// If the parton wasn't found, it must be a gluon
else {
return "g";
}
}
bool Col_str::gluons_only() const {
// Loop over Quark_lines
for (uint i = 0; i < cs.size(); i++) {
if (cs.at(i).open)
return false;
}
// If no Ql was open, the Cs has gluons only
return true;
}
int Col_str::n_gluon() const {
int ng = 0;
// Loop over Quark_lines
for (uint i = 0; i < cs.size(); i++) {
// If the ql is closed, all partons are gluons
// if it is open, all -2 are gluons
ng = ng+at(i).ql.size();
if (at(i).open) ng = ng - 2;
}
return ng;
}
int Col_str::n_quark() const {
int nq = 0;
// Loop over Quark_lines
for (uint i = 0; i < cs.size(); i++) {
// If the ql is closed, there is no gluon
// If it is open, there is one quark (and one anti-quark)
if (at(i).open) nq++;
}
return nq;
}
void Col_str::normal_order() {
// All individual quark_lines should be normal_ordered
for (uint i = 0; i < cs.size(); i++) {
cs.at(i).normal_order();
}
// Loop over the ql's which are candidates to move
for (uint i = 1; i < cs.size(); i++) {
// How many steps to the left should the ql be moved?
int steps_left = 0;
while (steps_left <= static_cast<int>(i) - 1 && compare_quark_lines(i, i - steps_left - 1) == static_cast<int>(i))
steps_left++;
if (steps_left != 0) {
// Insert ql in new place
cs.insert(cs.begin() + i - steps_left, cs.at(i));
// Eras in old
cs.erase(cs.begin() + i + 1);
}
}
}
int Col_str::smallest( const Col_str & Cs1, const Col_str & Cs2 ) const{
// First order Col_strs according to how many Quark_lines they have
// The Col_str with fewest Quark_lines is "smallest"
if ( Cs1.size() < Cs2.size() ) return 1;
else if( Cs2.size() < Cs1.size() ) return 2;
// First judge depending on if the Qls are open or not
// open ql's are "smaller"
for( uint i=0; i< std::min( Cs1.cs.size(), Cs2.cs.size() ); i++ ){
// The "smallest" Ql at place i
if (Cs1.cs.at(i).open && !Cs2.cs.at(i).open) return 1;
else if (Cs2.cs.at(i).open && !Cs1.cs.at(i).open) return 2;
}
// Then, judge depending on size of the Ql's
// longer qls are "smaller", should stand first
for( uint i=0; i< std::min( Cs1.cs.size(), Cs2.cs.size() ); i++ ){
// The "longest" Ql at place i
if ( Cs1.cs.at(i).ql.size() > Cs2.cs.at(i).ql.size() ) return 1;
else if (Cs2.cs.at(i).ql.size() > Cs1.cs.at(i).ql.size() ) return 2;
}
// Then, loop over the Quark_lines to see which ql is "smaller", taking index ordering into account
// First different index decides, ql with smallest index is smaller
for( uint i=0; i< std::min( Cs1.cs.size(), Cs2.cs.size() ); i++ ){
// The "smallest" Ql at place i
int OneOrTwo=Cs1.cs.at(i).smallest( Cs1.cs.at(i), Cs2.cs.at(i) );
if ( OneOrTwo==1 ) return 1;
else if( OneOrTwo==2 ) return 2;
}
//If the col_str's are identical, return 0
return 0;
}
int Col_str::longest_quark_line() const{
int length=0;
for ( uint j = 0; j < cs.size(); j++ ) {
if( static_cast<int> ( at(j).size() )> length ) length=static_cast<int> ( at(j).size() );
}
return length;
}
void Col_str::remove_1_rings() {
// Loop over quarl_lines
for (uint j = 0; j < cs.size(); j++) {
// If a quark_line contains only one gluon, replace whole Col_str with a 0-monomial
if (cs.at(j).ql.size() == 1) {
// If the quark_line is closed the Col_str is 0
if (!cs.at(j).open) {
// Remove irrelevant Polynomial and col_str
// The col_str is now multiplying 0
cs.clear();
Poly.clear();
Monomial Mon0;
Mon0.int_part = 0;
Poly.append(Mon0);
}
// If the Ql is open and has only one element, something is wrong
else if (cs.at(j).open) {
std::cerr
<< "Col_str::remove_1_rings: An open quark_line cannot have only one parton, but it had in \n"
<< cs << std::endl;
std::cerr.flush();
assert( 0 );
}
}
}
}
void Col_str::remove_0_rings() {
// Loop over Quark_lines
for (int j = 0; j < static_cast<int>(cs.size()); j++) {
// If a quark_line contains no gluons and is closed
// it is equal to Nc, move factor Nc to the Polynomial of the Col_str
if (cs.at(j).ql.size() == 0) {
// Move color factor of the Quark_line to the Polynomial of the Col_str
Poly = Poly * cs.at(j).Poly;
// Multiply with Nc if the quark_line is closed
if (!cs.at(j).open) {
Monomial Mon_tmp;
Mon_tmp.pow_Nc = 1;
Poly *= Mon_tmp;
}
// If the ql is open and has 0 elements,
// it is defined as 1 and can be removed
// Erase the Ql
erase(j);
// In order to check all elements, decrease j when Ql removed
// j may get to -1, so can not be seen as uint
j--;
}
}
}
void Col_str::simplify() {
remove_1_rings();
remove_0_rings();
// Move factors multiplying the individual Ql's to multiply
// the Col_str instead
for (uint i = 0; i < cs.size(); i++) {
Poly = Poly * cs.at(i).Poly;
cs.at(i).Poly.clear();
}
// Simplify Polynomial of Col_str
Poly.simplify();
// Normal order
normal_order();
}
void Col_str::conjugate(){
// Conjugating Polynomial
Poly.conjugate();
// Take conjugate of cs by conjugating each Quark_line
for (uint i=0; i < cs.size(); i++ ){
cs.at(i).conjugate();
}
}
int Col_str::compare_quark_lines( int i1, int i2 ) const {
int OneOrTwo= cs.at(i1).smallest( cs.at(i1), cs.at(i2) );
if ( OneOrTwo==1 ) return i1;
else if ( OneOrTwo==2 ) return i2;
// If ql's are equal, return i1
else if ( OneOrTwo==0 ) return i1;
else{
std::cerr << "Col_str::compare_quark_lines: cannot decide on ordering of quark_lines "
<< cs.at(i1) << " and " << cs.at(i2);
return 0;
}
}
void Col_str::contract_2_rings( ) {
// Contract gluons from 2-ring, this gives only one term
// For storing place of two-ring
std::vector<int> place1;
// For storing place of gluon with same index as second gluon in two-ring
// i.e. the gluon to be replaced with the first index in the 2-ring
std::vector<int> place2;
// The second index in two-ring, to be removed
int the_g;
// Loop over Quark_lines to find a two-ring
for ( uint i = 0; i < cs.size(); i++ ) {
place1.clear();
place2.clear();
// Search for 2-rings
// A gluon 2-ring has length 2 and is closed
if ( cs.at(i).ql.size() == 2 && !cs.at(i).open ) {
// Save place of two-ring
place1.push_back(i);
// Pick second gluon (for no good reason)
// this index should be replaced by first index
// in the other place where it occurs, and the 2-ring should be removed
place1.push_back(1);
the_g = at(place1.at(0), place1.at(1));
// Now, in all Quark_lines, look for same the_g until found
for ( uint i2 = 0; i2 < size(); i2++ ) {
for (uint j2 = 0; j2 < at(i2).ql.size(); j2++) {
// If the_g was found at a DIFFERENT place, (not same g again)
if ((i2 != i or j2 != 1) && at(i2, j2) == the_g) {
place2.push_back(i2);
place2.push_back(j2);
}
}
}
// Check that the gluon index was found again
if (place2.empty()) {
std::cerr << "Col_str:contract_2_rings: Only found the index " << the_g
<< " once in " << *this << std::endl;
assert( 0 );
}
// If the_g was found twice in the same ql
if ( place1.at(0) == place2.at(0) ) {
// Keep the Monomial
// Multiply with Nc Mon from the contraction
Monomial Mon_tmp;
Mon_tmp.pow_Nc = 1;
Mon_tmp.pow_CF = 1;
// Multiply the Poly of the Col_str with the Poly of the ql
// and the color factor from the contraction
Poly = Poly* cs.at(place1.at(0)).Poly * Mon_tmp;
// Erase the ql
erase(place1.at(0));
}
else if ( !place2.empty() ){
// That index should be changed to the index of the first gluon
// in the 2-ring
cs.at(place2.at(0)).ql.at(place2.at(1))
= at(place1.at(0), 0);
// Multiply the Poly of the Col_str with the Poly of the ql
// and the color factor from the contraction
Monomial Mon_tmp;
Mon_tmp.pow_TR = 1;
Poly = Poly * Mon_tmp*cs.at(place1.at(0)).Poly;
// The two ring should be removed
cs.erase( cs.begin() + i);
}
//else {i++;}; // Compensate for i--
i--; // if we found a 2-ring, we also erased it
} // end if we found a 2-ring
}// end looping over Quark_lines
// One-rings may have been created
remove_1_rings();
return;
}
void Col_str::contract_quarks( const Col_str Cs1, const Col_str Cs2 ) {
if( !cs.empty() or Poly.size()!=0 ){
std::cerr
<< "Col_str::contract_quarks(Cs1,Cs2): This member function "
<< "stores the result from contracting quarks in the Col_str itself. "
<< "It therefore expects an empty initially Col_str, but it was:" << *this << std::endl;
}
std::vector<int> q_place;
std::vector<int> q_place2;
// The conjugate of Cs1
Col_str conj_Cs1 = Cs1;
conj_Cs1.conjugate();
// The total color structure
*this = conj_Cs1*Cs2;
// Count how many quarks should be contracted
int n_q = n_quark();
// As long as there are quark_lines left to contract
while (n_q > 0) {
// Find first quark in Cs1 by looping over Quark_lines
for (int i = 0; (n_q>0 && i < static_cast<int>( size()) ); i++) {
// Check if the quark-line is open, in which case it has a q
if ( cs.at(i).open ) {
// The first quark is located and has position
q_place.clear();
q_place.push_back(i);
q_place.push_back(0);
// and number
int q = at(q_place.at(0), q_place.at(1));
// Locate same quark a second time
// Loop over Quark_lines
q_place2.clear();
int i2 = i + 1; // Quark_line of second occurrence
while (q_place2.empty()) { // As long as quark not found a second time
if ( cs.at(i2).at( cs.at(i2).ql.size() - 1) == q) {// If quark found, store place
q_place2.push_back(i2);
q_place2.push_back( cs.at(i2).ql.size() - 1);
}
i2++;
}
if (q_place2.empty()) {
std::cerr << "Col_functions::contract_quarks(Cs1, Cs2): Found q " << q
<< " only once in " << *this << std::endl;
}
// Prepare new Quark_line
// to be inserted at the place of found open Quark_line
Quark_line new_Quark_line;
Quark_line part2_new_Quark_line;
// The first part of the new Quark_line should be the Quark_line
// containing q in the conjugate
new_Quark_line = cs.at(q_place2.at(0));
// Erasing q in the end
new_Quark_line.ql.erase(--new_Quark_line.ql.end());
part2_new_Quark_line = cs.at(q_place.at(0));
// Erasing the q in the beginning of second part
part2_new_Quark_line.ql.erase(part2_new_Quark_line.ql.begin());
new_Quark_line.append(part2_new_Quark_line.ql);
// So far we have not included the Polynomial of part2_new_Quark_line
new_Quark_line.Poly=new_Quark_line.Poly*part2_new_Quark_line.Poly;
// If the first q index and the last qbar index in the new
// Quark_line is the same (and the Quark_line is "open"), the indices
// should be removed and the Quark_line should be closed
if (new_Quark_line.ql.at(0) == new_Quark_line.ql.at(
new_Quark_line.ql.size() - 1) && new_Quark_line.open) {
// The string is closed
new_Quark_line.open = false;
// Remove last and first index
new_Quark_line.ql.erase(--new_Quark_line.ql.end(),
new_Quark_line.ql.end());
new_Quark_line.ql.erase(new_Quark_line.ql.begin());
}
// Inserting new Quark_line in the place of the old
cs.at(i) = new_Quark_line;
// Remove quark_line with q in Cs
cs.erase(( cs.begin() + q_place2.at(0)));
i=-1; // reset to keep looking from the beginning in the new Cs (i will be increased to 0)
}// end of if (open)
n_q = n_quark();
} // end of for, loop over quark_lines
} // end while (n_q > 0)
return;
}
void Col_str::contract_next_neighboring_gluons( ) {
// Loop over Quark_lines and remove neighboring and next to neighboring
// gluon indices
for( uint i=0; i < cs.size(); i++ ){
// Create a Quark_line to use as argument
Quark_line Ql= at(i);
Ql.contract_next_neighboring_gluons( );
// Collect Polynomial in Cs Polynomial
Poly=Poly*Ql.Poly;
// and put powers in Ql to 0
Ql.Poly.clear();
cs.insert( cs.begin() +i, Ql);
// Erase old version of Quark_line (now at place i+1)
cs.erase( cs.begin() +i + 1 );
}
// Remove 1 and 0-rings, simplify Poly and normal order
simplify();
return;
}
bool operator==( const col_str & cs1, const col_str & cs2 ){
// col_str's must have equal length
if( cs1.size() != cs2.size() ) return false;
// Individual Ql's be be equal
for ( uint i=0; i< cs1.size(); i++){
if(cs1.at(i) != cs2.at(i) ) return false;
}
//If all ql's equal the cs are considered equal
return true;
}
bool operator!=( const col_str & cs1, const col_str & cs2 ){
if(cs1==cs2) return false;
else return true;
}
std::ostream& operator<<( std::ostream& out, const col_str & cs ) {
int max = cs.size();
if (max == 0)
out << "[]";
else {
out << "[";
for (int i = 0; i < max - 1; i++) {
out << cs.at(i);
}
out << cs.at(max - 1) << "]"; //<< std::endl;
}
return out;
}
Col_str operator*( const Col_str & Cs, const int i){
Col_str Cs_res=Cs;
Cs_res.Poly=Cs.Poly*i;
return Cs_res;
}
// Define the operator * for int and Col_str
Col_str operator*( const int i, const Col_str & Cs ){
Col_str Cs_res=Cs;
Cs_res.Poly=Cs.Poly*i;
return Cs_res;
}
Col_str operator*( const Col_str & Cs, const double d ){
// Multiply Polynomial of Col_str with the double
Col_str Cs_res=Cs;
Cs_res.Poly *= d;
return Cs_res;
}
Col_str operator*( const double d, const Col_str & Cs ){
Col_str Cs_res=Cs;
Cs_res.Poly=Cs.Poly*d;
return Cs_res;
}
Col_str operator*(const Col_str & Cs, const cnum c ){
Col_str Cs_res=Cs;
Cs_res.Poly=Cs.Poly*c;
return Cs_res;
return Cs;
}
Col_str operator*( const cnum c, const Col_str & Cs ){
Col_str Cs_res=Cs;
Cs_res.Poly=Cs.Poly*c;
return Cs_res;
}
Col_str operator* (const Col_str & Cs, const Monomial & Mon ){
Col_str Cs_res=Cs;
Cs_res.Poly =Cs.Poly*Mon;
return Cs_res;
}
Col_str operator*( Monomial & Mon, const Col_str & Cs ){
Col_str Cs_res=Cs;
Cs_res.Poly=Cs.Poly*Mon;
return Cs_res;
}
Col_str operator*( const Col_str & Cs, const Polynomial & Poly ){
Col_str Cs_res=Cs;
Cs_res.Poly=Cs.Poly*Poly;
return Cs_res;
}
Col_str operator*( const Polynomial & Poly, const Col_str & Cs ){
Col_str Cs_res=Cs;
Cs_res.Poly=Cs.Poly*Poly;
return Cs_res;
}
Col_str operator*( const Col_str & Cs, const Quark_line & Ql){
// Col_str to return
Col_str out_Cs=(Cs);
// Quark_line copy
Quark_line out_Ql(Ql);
// Multiplying Polynomials
out_Cs.Poly = out_Ql.Poly*Cs.Poly;
// Remove Polynomial info from Quark_line (put to 1),
// as this info is stored in Polynomial of Col_str instead
out_Ql.Poly.clear();
// Append Quark_line (without multiplicative polynomial) to out_Col_str
out_Cs.cs.push_back( out_Ql );
return out_Cs;
}
Col_str operator*( const Quark_line & Ql , const Col_str & Cs){
return Cs*Ql;
}
Col_str operator*( const Col_str & Cs1, const Col_str & Cs2 ){
// Col_str to return
Col_str out_Cs=Cs1;
// Multiplying Polynomials
out_Cs.Poly = Cs1.Poly*Cs2.Poly;
// Looping over Quark_lines in Cs2 to add to Cs1
for (uint i=0; i < Cs2.cs.size(); i++ ){
// Append i:th Quark_line at i:th place in out_Col_str
out_Cs.cs.push_back( Cs2.cs.at(i) );
}
return out_Cs;
}
Col_str operator*( const Quark_line & Ql1, const Quark_line & Ql2 ){
// Col_str to return
Col_str out_Cs(Ql1);
out_Cs.simplify();
return out_Cs*Ql2;
}
std::ostream& operator<<(std::ostream& out, const Col_str & Cs){
// Write out polynomial if it is not 1, or if the cs has no structure
Polynomial Poly1; // For comparison, the default Polynomial=1
if( Cs.Poly!=Poly1 or Cs.cs.size()==0 ) out << Cs.Poly;
out << Cs.cs;
return out;
}
bool operator==(const Col_str & Cs1, const Col_str & Cs2){
// col_str's be equal
if( Cs1.cs != Cs2.cs ) return false;
// Poly's must be equal
if( Cs1.Poly != Cs2.Poly ) return false;
//If all col_strs and all Polynomials are equal the Col_strs are considered equal
return true;
}
bool operator!=( const Col_str & Cs1, const Col_str & Cs2){
if( Cs1==Cs2 ) return false;
else return true;
}
} //end namespace ColorFull
diff --git a/Shower/QTilde/Base/ShowerParticle.h b/Shower/QTilde/Base/ShowerParticle.h
--- a/Shower/QTilde/Base/ShowerParticle.h
+++ b/Shower/QTilde/Base/ShowerParticle.h
@@ -1,550 +1,551 @@
// -*- C++ -*-
//
// ShowerParticle.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_ShowerParticle_H
#define HERWIG_ShowerParticle_H
//
// This is the declaration of the ShowerParticle class.
//
#include "ThePEG/EventRecord/Particle.h"
#include "Herwig/Shower/QTilde/SplittingFunctions/SplittingFunction.fh"
#include "Herwig/Shower/QTilde/ShowerConfig.h"
#include "Herwig/Shower/QTilde/Kinematics/ShowerBasis.h"
#include "Herwig/Shower/QTilde/Kinematics/ShowerKinematics.h"
#include "ShowerParticle.fh"
#include <iosfwd>
namespace Herwig {
using namespace ThePEG;
/** \ingroup Shower
* This class represents a particle in the showering process.
* It inherits from the Particle class of ThePEG and has some
* specifics information useful only during the showering process.
*
* Notice that:
* - for forward evolution, it is clear what is meant by parent/child;
* for backward evolution, however, it depends whether we want
* to keep a physical picture or a Monte-Carlo effective one.
* In the former case, an incoming particle (emitting particle)
* splits into an emitted particle and the emitting particle after
* the emission: the latter two are then children of the
* emitting particle, the parent. In the Monte-Carlo effective
* picture, we have that the particle close to the hard subprocess,
* with higher (space-like) virtuality, splits into an emitted particle
* and the emitting particle at lower virtuality: the latter two are,
* in this case, the children of the first one, the parent. However we
* choose a more physical picture where the new emitting particle is the
* parented of the emitted final-state particle and the original emitting
* particle.
* - the pointer to a SplitFun object is set only in the case
* that the particle has undergone a shower emission. This is similar to
* the case of the decay of a normal Particle where
* the pointer to a Decayer object is set only in the case
* that the particle has undergone to a decay.
* In the case of particle connected directly to the hard subprocess,
* there is no pointer to the hard subprocess, but there is a method
* isFromHardSubprocess() which returns true only in this case.
*
* @see Particle
* @see ShowerConfig
* @see ShowerKinematics
*/
class ShowerParticle: public Particle {
public:
/**
* Struct for all the info on an evolution partner
*/
struct EvolutionPartner {
/**
* Constructor
*/
EvolutionPartner(tShowerParticlePtr p,double w, ShowerPartnerType t,
Energy s) : partner(p), weight(w), type(t), scale(s)
{}
/**
* The partner
*/
tShowerParticlePtr partner;
/**
* Weight
*/
double weight;
/**
* Type
*/
ShowerPartnerType type;
/**
* The assoicated evolution scale
*/
Energy scale;
};
/**
* Struct to store the evolution scales
*/
struct EvolutionScales {
/**
* Constructor
*/
EvolutionScales() : QED(),QED_noAO(),QCD_c(),QCD_ac(),
- QCD_c_noAO(),QCD_ac_noAO(),DARK_c(),
- DARK_ac(),DARK_c_noAO(),DARK_ac_noAO()
+ QCD_c_noAO(),QCD_ac_noAO(),
+ EW(),
+ DARK_c(), DARK_ac(),DARK_c_noAO(),DARK_ac_noAO()
{}
/**
* QED scale
*/
Energy QED;
/**
* QCD colour scale
*/
Energy QCD_c;
/**
* QCD anticolour scale
*/
Energy QCD_ac;
/**
* QED scale
*/
Energy QED_noAO;
/**
* QCD colour scale
*/
Energy QCD_c_noAO;
/**
* QCD anticolour scale
*/
Energy QCD_ac_noAO;
/**
* EW scales
*/
Energy EW;
/**
* DARK scales
*/
Energy DARK_c;
/**
* DARK anticolour scale
*/
Energy DARK_ac;
/**
* DARK colour scale
*/
Energy DARK_c_noAO;
/**
* DARK anticolour scale
*/
Energy DARK_ac_noAO;
};
/** @name Construction and descruction functions. */
//@{
/**
* Standard Constructor. Note that the default constructor is
* private - there is no particle without a pointer to a
* ParticleData object.
* @param x the ParticleData object
* @param fs Whether or not the particle is an inital or final-state particle
* @param tls Whether or not the particle initiates a time-like shower
*/
ShowerParticle(tcEventPDPtr x, bool fs, bool tls=false)
: Particle(x), _isFinalState(fs),
_perturbative(0), _initiatesTLS(tls), _x(1.0), _showerKinematics(),
_vMass(ZERO), _thePEGBase() {}
/**
* Copy constructor from a ThePEG Particle
* @param x ThePEG particle
* @param pert Where the particle came from
* @param fs Whether or not the particle is an inital or final-state particle
* @param tls Whether or not the particle initiates a time-like shower
*/
ShowerParticle(const Particle & x, unsigned int pert, bool fs, bool tls=false)
: Particle(x), _isFinalState(fs),
_perturbative(pert), _initiatesTLS(tls), _x(1.0), _showerKinematics(),
_vMass(ZERO), _thePEGBase(&x) {}
//@}
public:
/**
* Set a preliminary momentum for the particle
*/
void setShowerMomentum(bool timelike);
/**
* Construct the spin info object for a shower particle
*/
void constructSpinInfo(bool timelike);
/**
* Perform any initial calculations needed after the branching has been selected
*/
void initializeDecay();
/**
* Perform any initial calculations needed after the branching has been selected
* @param parent The beam particle
*/
void initializeInitialState(PPtr parent);
/**
* Perform any initial calculations needed after the branching has been selected
*/
void initializeFinalState();
/**
* Access/Set various flags about the state of the particle
*/
//@{
/**
* Access the flag that tells if the particle is final state
* or initial state.
*/
bool isFinalState() const { return _isFinalState; }
/**
* Access the flag that tells if the particle is initiating a
* time like shower when it has been emitted in an initial state shower.
*/
bool initiatesTLS() const { return _initiatesTLS; }
/**
* Access the flag which tells us where the particle came from
* This is 0 for a particle produced in the shower, 1 if the particle came
* from the hard sub-process and 2 is it came from a decay.
*/
unsigned int perturbative() const { return _perturbative; }
//@}
/**
* Set/Get the momentum fraction for initial-state particles
*/
//@{
/**
* For an initial state particle get the fraction of the beam momentum
*/
void x(double x) { _x = x; }
/**
* For an initial state particle set the fraction of the beam momentum
*/
double x() const { return _x; }
//@}
/**
* Set/Get methods for the ShowerKinematics objects
*/
//@{
/**
* Access/ the ShowerKinematics object.
*/
const ShoKinPtr & showerKinematics() const { return _showerKinematics; }
/**
* Set the ShowerKinematics object.
*/
void showerKinematics(const ShoKinPtr in) { _showerKinematics = in; }
//@}
/**
* Set/Get methods for the ShowerBasis objects
*/
//@{
/**
* Access/ the ShowerBasis object.
*/
const ShowerBasisPtr & showerBasis() const { return _showerBasis; }
/**
* Set the ShowerBasis object.
*/
void showerBasis(const ShowerBasisPtr in, bool copy) {
if(!copy)
_showerBasis = in;
else {
_showerBasis = new_ptr(ShowerBasis());
_showerBasis->setBasis(in->pVector(),in->nVector(),in->frame());
}
}
//@}
/**
* Members relating to the initial evolution scale and partner for the particle
*/
//@{
/**
* Veto emission at a given scale
*/
void vetoEmission(ShowerPartnerType type, Energy scale);
/**
* Access to the evolution scales
*/
const EvolutionScales & scales() const {return scales_;}
/**
* Access to the evolution scales
*/
EvolutionScales & scales() {return scales_;}
/**
* Return the virtual mass\f$
*/
Energy virtualMass() const { return _vMass; }
/**
* Set the virtual mass
*/
void virtualMass(Energy mass) { _vMass = mass; }
/**
* Return the partner
*/
tShowerParticlePtr partner() const { return _partner; }
/**
* Set the partner
*/
void partner(const tShowerParticlePtr partner) { _partner = partner; }
/**
* Get the possible partners
*/
vector<EvolutionPartner> & partners() { return partners_; }
/**
* Add a possible partners
*/
void addPartner(EvolutionPartner in );
/**
* Clear the evolution partners
*/
void clearPartners() { partners_.clear(); }
/**
* Return the progenitor of the shower
*/
tShowerParticlePtr progenitor() const { return _progenitor; }
/**
* Set the progenitor of the shower
*/
void progenitor(const tShowerParticlePtr progenitor) { _progenitor = progenitor; }
//@}
/**
* Members to store and provide access to variables for a specific
* shower evolution scheme
*/
//@{
struct Parameters {
Parameters() : alpha(1.), beta(), ptx(), pty(), pt() {}
double alpha;
double beta;
Energy ptx;
Energy pty;
Energy pt;
};
/**
* Set the vector containing dimensionless variables
*/
Parameters & showerParameters() { return _parameters; }
//@}
/**
* If this particle came from the hard process get a pointer to ThePEG particle
* it came from
*/
const tcPPtr thePEGBase() const { return _thePEGBase; }
public:
/**
* Extract the rho matrix including mapping needed in the shower
*/
RhoDMatrix extractRhoMatrix(bool forward);
/**
* For a particle which came from the hard process get the spin density and
* the mapping required to the basis used in the Shower
* @param rho The \f$\rho\f$ matrix
* @param mapping The mapping
* @param showerkin The ShowerKinematics object
*/
bool getMapping(SpinPtr &, RhoDMatrix & map);
protected:
/**
* Standard clone function.
*/
virtual PPtr clone() const;
/**
* Standard clone function.
*/
virtual PPtr fullclone() const;
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<ShowerParticle> initShowerParticle;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
ShowerParticle & operator=(const ShowerParticle &) = delete;
private:
/**
* Whether the particle is in the final or initial state
*/
bool _isFinalState;
/**
* Whether the particle came from
*/
unsigned int _perturbative;
/**
* Does a particle produced in the backward shower initiate a time-like shower
*/
bool _initiatesTLS;
/**
* Dimensionless parameters
*/
Parameters _parameters;
/**
* The beam energy fraction for particle's in the initial state
*/
double _x;
/**
* The shower kinematics for the particle
*/
ShoKinPtr _showerKinematics;
/**
* The shower basis for the particle
*/
ShowerBasisPtr _showerBasis;
/**
* Storage of the evolution scales
*/
EvolutionScales scales_;
/**
* Virtual mass
*/
Energy _vMass;
/**
* Partners
*/
tShowerParticlePtr _partner;
/**
* Pointer to ThePEG Particle this ShowerParticle was created from
*/
const tcPPtr _thePEGBase;
/**
* Progenitor
*/
tShowerParticlePtr _progenitor;
/**
* Partners
*/
vector<EvolutionPartner> partners_;
};
inline ostream & operator<<(ostream & os, const ShowerParticle::EvolutionScales & es) {
os << "Scales: QED=" << es.QED / GeV
<< " QCD_c=" << es.QCD_c / GeV
<< " QCD_ac=" << es.QCD_ac / GeV
<< " EW=" << es.EW / GeV
<< " QED_noAO=" << es.QED_noAO / GeV
<< " QCD_c_noAO=" << es.QCD_c_noAO / GeV
<< " QCD_ac_noAO=" << es.QCD_ac_noAO / GeV
<< '\n';
return os;
}
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of ShowerParticle. */
template <>
struct BaseClassTrait<Herwig::ShowerParticle,1> {
/** Typedef of the first base class of ShowerParticle. */
typedef Particle NthBase;
};
/** This template specialization informs ThePEG about the name of
* the ShowerParticle class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::ShowerParticle>
: public ClassTraitsBase<Herwig::ShowerParticle> {
/** Return a platform-independent class name */
static string className() { return "Herwig::ShowerParticle"; }
/** Create a Event object. */
static TPtr create() { return TPtr::Create(Herwig::ShowerParticle(tcEventPDPtr(),true)); }
};
/** @endcond */
}
#endif /* HERWIG_ShowerParticle_H */
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Dec 21, 3:41 PM (1 d, 6 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4023325
Default Alt Text
(39 KB)
Attached To
rHERWIGHG herwighg
Event Timeline
Log In to Comment