int PP6Muon() { std::string muonFile; int resultCode(0); // Obtain filename from user std::cout << "Enter filename to analyse: "; muonFile = getString(); std::string runID("run4.dat"); int numberOfMuons(0), numberOfAntiMuons(0); // Count number of muons/antimuons in input file resultCode = countMuons(muonFile, runID, numberOfMuons, numberOfAntiMuons); if (resultCode) { std::cerr << "[PP6Muon:error] Failed to count muons in " << muonFile << std::endl; return resultCode; } //-------------------------------------------------------------------- // - Create arrays to hold muon data int *muonEventNumber(new int[numberOfMuons]); double *muonEnergy(new double[numberOfMuons]); double *muonPx(new double[numberOfMuons]); double *muonPy(new double[numberOfMuons]); double *muonPz(new double[numberOfMuons]); int *antimuonEventNumber(new int[numberOfAntiMuons]); double *antimuonEnergy(new double[numberOfAntiMuons]); double *antimuonPx(new double[numberOfAntiMuons]); double *antimuonPy(new double[numberOfAntiMuons]); double *antimuonPz(new double[numberOfAntiMuons]); // - Read in data int eventNumber(0); std::string particleName, dataID; double particlePx(0), particlePy(0), particlePz(0); double particlePtot(0); const double muonMass(0.105658366); FileReader muonReader(muonFile); int muonCounter(0); int antimuonCounter(0); while (muonReader.nextLine()) { // Valid lines should begin with an integer, continue without error // to skip header eventNumber = muonReader.getField<int>(1); if (muonReader.inputFailed()) continue; particleName = muonReader.getField<std::string>(2); if (muonReader.inputFailed()) { std::cerr << "[PP6Muon:error] Field 2 of " << muonFile << " is not a string" << std::endl; break; } dataID = muonReader.getField<std::string>(6); if (muonReader.inputFailed()) { std::cerr << "[PP6Muon:error] Field 6 of " << muonFile << " is not a string" << std::endl; break; } if (dataID == runID) { // Read the physics data particlePx = muonReader.getField<double>(3); if (muonReader.inputFailed()) { std::cerr << "[PP6Muon:error] Field 3 of " << muonFile << " is not a double" << std::endl; break; } particlePy = muonReader.getField<double>(4); if (muonReader.inputFailed()) { std::cerr << "[PP6Muon:error] Field 4 of " << muonFile << " is not a double" << std::endl; break; } particlePz = muonReader.getField<double>(5); if (muonReader.inputFailed()) { std::cerr << "[PP6Muon:error] Field 5 of " << muonFile << " is not a double" << std::endl; break; } if (particleName == "mu-") { // Fill muon data muonEventNumber[muonCounter] = eventNumber; muonPx[muonCounter] = particlePx; muonPy[muonCounter] = particlePy; muonPz[muonCounter] = particlePz; length3(particlePx, particlePy, particlePz, particlePtot); muonEnergy[muonCounter] = sqrt(particlePtot * particlePtot + muonMass*muonMass); ++muonCounter; } if (particleName == "mu+") { // Fill antimuon data antimuonEventNumber[antimuonCounter] = eventNumber; antimuonPx[antimuonCounter] = particlePx; antimuonPy[antimuonCounter] = particlePy; antimuonPz[antimuonCounter] = particlePz; length3(particlePx, particlePy, particlePz, particlePtot); antimuonEnergy[antimuonCounter] = sqrt(particlePtot * particlePtot + muonMass*muonMass); ++antimuonCounter; } } } if (muonReader.inputFailed()) { // - Clean up and return std::cerr << "[PP6Muon:error] Failed to extract physics data from " << muonFile << std::endl; delete [] muonEventNumber; delete [] muonEnergy; delete [] muonPx; delete [] muonPy; delete [] muonPz; delete [] antimuonEventNumber; delete [] antimuonEnergy; delete [] antimuonPx; delete [] antimuonPy; delete [] antimuonPz; return 1; } //-------------------------------------------------------------------- // - Analyse data... // Invariant mass and indexing array double *invariantMass(new double[numberOfMuons * numberOfAntiMuons]); int *muonPairIndex(new int[numberOfMuons * numberOfAntiMuons]); // - Loop over mu-/mu+ arrays, calculating invariant masses as we go for (int i(0); i < numberOfAntiMuons; ++i) { for (int j(0); j < numberOfMuons; ++j) { inv_mass(muonEnergy[i], muonPx[i], muonPy[i], muonPz[i], antimuonEnergy[j], antimuonPx[j], antimuonPy[j], antimuonPz[j], invariantMass[i*numberOfMuons + j]); muonPairIndex[i*numberOfMuons + j] = i*numberOfMuons + j; } } // Use associative sort to sort masses associative_sort(invariantMass, muonPairIndex, numberOfMuons * numberOfAntiMuons); //-------------------------------------------------------------------- // - Present results // std::cout << "Results:" << std::endl; std::cout << "========" << std::endl; std::cout << "Analysed File : " << muonFile << std::endl; std::cout << "Number of Muons = " << numberOfMuons << std::endl; std::cout << "Number of AntiMuons = " << numberOfAntiMuons << std::endl; std::cout << "----------------------------" << std::endl; for (int i(0); i < 10; ++i) { int muonIndex(muonPairIndex[i] % numberOfMuons); int antimuonIndex((muonPairIndex[i] - muonIndex) / numberOfMuons); std::cout << "{InvariantMass : " << invariantMass[muonPairIndex[i]] << ",\n\t" << "{Muon : " << "Event = " << muonEventNumber[muonIndex] << ", " << "(E, P) = (" << muonEnergy[muonIndex] << ", " << muonPx[muonIndex] << ", " << muonPy[muonIndex] << ", " << muonPz[muonIndex] << ")}\n\t" << "{AntiMuon : " << "Event = " << antimuonEventNumber[antimuonIndex] << ", " << "(E, P) = (" << antimuonEnergy[antimuonIndex] << ", " << antimuonPx[antimuonIndex] << ", " << antimuonPy[antimuonIndex] << ", " << antimuonPz[antimuonIndex] << ")}\n" << "}" << std::endl; } // - Clean up arrays delete [] muonEventNumber; delete [] muonEnergy; delete [] muonPx; delete [] muonPy; delete [] muonPz; delete [] antimuonEventNumber; delete [] antimuonEnergy; delete [] antimuonPx; delete [] antimuonPy; delete [] antimuonPz; delete [] invariantMass; delete [] muonPairIndex; return 0; }
int pp6day3_muonanalysis() { std::string muonFile; //int resultCode(0); // Obtain filename from user std::cout << "Enter filename to analyse: "; muonFile = getString(); // Create EventArrays of muons/antimuons in input file std::string runID("run4.dat"); double muonMass = 0.105658366; // GeV EventArray* p = readParticles(muonFile, "mu-", muonMass, runID); EventArray* q = readParticles(muonFile, "mu+", muonMass, runID); // Create an array of suffcient size to hold the invariant masses // formed between each muon/antimuon pair, plus an array // to hold the flattened indices int combinations = p->size * q->size; double *invMasses = new double[combinations]; int *indices = new int[combinations]; for (size_t i(0); i < q->size; ++i) { for (size_t j(0); j < p->size; ++j) { int flatIndex = i * p->size + j; indices[flatIndex] = flatIndex; invMasses[flatIndex] = calculate_invariant_mass(q->particles[i], p->particles[j]); } } // Sort the invariant masses using an associative sort over the indices associative_sort(invMasses, indices, combinations); //-------------------------------------------------------------------- // - Present results // std::cout << "Results:" << std::endl; std::cout << "========" << std::endl; std::cout << "Analysed File : " << muonFile << std::endl; std::cout << "Number of Muons = " << p->size << std::endl; std::cout << "Number of AntiMuons = " << q->size << std::endl; std::cout << "----------------------------" << std::endl; for (int i(0); i < 10; ++i) { int muonIndex(indices[i] % p->size); int antimuonIndex((indices[i] - muonIndex) / p->size); std::cout << "{InvariantMass : " << invMasses[indices[i]] << ",\n\t" << "{Muon : " << "Event = " << p->ids[muonIndex] << ", " << "(E, P) = (" << (p->particles[muonIndex]).getFourMomentum() << ")}\n\t" << "{AntiMuon : " << "Event = " << q->ids[antimuonIndex] << ", " << "(E, P) = (" << (q->particles[antimuonIndex]).getFourMomentum() << ")}\n" << "}" << std::endl; } destroyEventArray(p); destroyEventArray(q); delete [] invMasses; delete [] indices; return 0; }