Beispiel #1
0
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;
}