The Parameters class stores several std::vectors, one each for neutrino flavors (NuFlav), parents (Parent), cross sections (std::string matching one entry from XSec::ListIntTypes), and detectors (std::string matching output from Detector::GetDetName). This object is given as an input to FluxReader::AddSpectra to create each Spectra and determines how to split the distributions in the Spectra. It also maintains an internal indexing scheme to identify a specific histogram by reference to a given flavor, parent, cross section, and detector.


When constructing a Parameters object, the user must decide two things: whether the sign of the neutrino parent should be considered or ignored, and how verbose the warnings of Parameters will be. By default, the sign is considered, but an optional boolean can be specified as false in order to treat the parent particle and anti-particle together.

  Parameters params_parent_sign_separate(true); // Omitting the boolean would accomplish the same thing
  Parameters params(false);

Whenever a Parameters object is constructed, it automatically sets defaults for neutrino flavors, parents, and cross sections. The default neutrino flavors are the electron neutrino, anti-electron neutrino, muon neutrino, and anti-muon neutrino. The default parent species are mu plus and mu minus (muon), pi plus and pi minus (pion), K plus and K minus (kaon), and K Long. If parent sign is ignored, the positive and negative charged species are replaced by the single species in parenthesis, and the K Long is unaffected. The default cross sections are charged current (tot_cc), neutral current (tot_nc), and no cross section (NoXSec). There are no default detectors set.

The second input to the constructor is also optional, and is true by default.

  Parameters params_verbose(false, true); // Omitting the second boolean would accomplish the same thing
  Parameters params_quiet(false, false);

By turning off verbosity, two warning messages will never be displayed. Whenever Parameters searches its internal vectors for a particular neutrino flavor or parent, it outputs a warning if no match is found. This can sometimes be desired behavior since flavors and parents can be removed by the user. Turning off the verbosity will quiet the expected warnings in this case. However, instead of turning off the verbosity a better practice might be to run the ROOT macro with output redirected to a log file. See the discussion of the nohup command on the Setting Up and Running FluxReader page for more information.

General Use

The most important functions to the user are the various Add and Remove functions. There is a single Add function for each parameter except neutrino flavors. AddParent takes a Parent object, AddDetector takes a Detector, and AddXSec takes a std::string, but it must match something found in XSec::ListIntTypes. In order to add neutrino flavors, the ResetNuFlavs function must be used, which forces the NuFlav to include all of the default flavors as well as the tau neutrino and anti-tau neutrino.

Unlike the Add functions, there is at least one Remove function for each parameter, and sometimes more. RemoveDetector and RemoveXSec both take a std::string for input, and they remove any internally stored Detector that has a matching name or cross section that directly matches the input string. No change is made if nothing internally stored matches. RemoveNuFlav and RemoveParent each have three versions. Both can be called with a std::string, and any neutrino flavor or parent species that has a name that matches the input string will be removed. The second version uses an input integer, and any neutrino flavor or parent species that has a PDG code that matches the input integer will be removed. Finally, RemoveNuFlav can be called with a NuFlav object, and RemoveParent with a Parent object. In this case, both the stored name and PDG code must match in order for the internally stored object to be removed.

Before demonstrating these function calls, it is important to note that order matters. If a Remove function is called on a particular parameter and then an Add function is called on the same parameter, the parameter will end up being stored. However, if the Add function is called first, the parameter will end up being removed since the Remove function is called second.

  params.RemoveParent("muon"); // Get rid of the muon parent species
  params.RemoveParent(13); // This won't do anything since the call above already did this
  params.RemoveParent(Parent::kMuon); // This still won't do anything new

  params.AddParent(Parent::kMuon); // Add back in the muon

  params.ResetNuFlavs(); // Add ALL the neutrino flavors
  params.RemoveNuFlav(16); // Remove the tau neutrino
  params.RemoveNuFlav("anutau"); // Remove the anti-tau neutrino

  params.RemoveXSec("tot_cc"); // Remove the charged current cross section
  params.AddXSec("tot_cc"); // Changed my mind

  // This is a valid function call, but won't do anything since the input string is not a valid cross section

  params.AddDetector(knova_nd); // Add NOvA ND
  params.AddDetector(knova_fd); // Add NOvA FD
  params.RemoveDetector("nova_fd"); // Actually, no NOvA FD

Two other special functions for adding/removing parameters. RemoveNuTaus takes no arguments and essentially gets rid of the tau and anti-tau neutrino from the neutrino flavors. SetDefaults the neutrino flavors, parent species, and cross sections to the default that came from the constructor with the addition of the tau and anti-tau neutrinos in the flavors vector.

  // At this point, params should appear exactly as it did immediately after construction, with the addition of any added detectors

Once a Detector has been added to the parameters list, the user can change the number of times a neutrino ray will be smeared throughout its detector volume, using the SetDetUses function. The user must first specify a detector by its name as a std::string, then sets the number of neutrino ray uses by integer.

  params.SetDetUses("nova_nd", 3);

At any point, the user can check the number of any one particular parameter, using either NFlav, NPar, NXSec, or NDet.

  std::cout << "The current Parameters object has..." << std::endl;
  std::cout << params.NFlav() << " flavors,"        << std::endl;
  std::cout << params.NPar()  << " parents,"        << std::endl;
  std::cout << params.NXSec() << " cross sections," << std::endl;
  std::cout << params.NDet()  << " detectors."      << std::endl;

The user can access the sensitivity to parent sign as a boolean with the IsSignSensitive function.

  std::cout << "T or F: The current Parameters object is sensitive to parent sign: " << params.IsSignSensitive() << std::endl;

The remaining publicly accessible functions are of limited use to the user, probably only for debugging purposes. As mentioned above, Parameters has its own indexing method. In a bit more detail, this method stores a current index for each parameter vector, and can combine all four of these indices into one master index in a unique way. The current index for each parameter and the current master can all be accessed using an appropriate GetCurrent<Parameter> function, replacing <Parameter> by the appropriate label.

  std::cout << "The current master index is "   << params.GetCurrentMaster() << std::endl;
  std::cout << "The current flavor index is "   << params.GetCurrentNuFlav() << std::endl;
  std::cout << "The current parent index is "   << params.GetCurrentParent() << std::endl;
  std::cout << "The current xsec index is "     << params.GetCurrentXSec()   << std::endl;
  std::cout << "The current detector index is " << params.GetCurrentDet()    << std::endl;

With a current index, the user can directly access some of the fields in the stored parameters vectors, using the functions GetDetName, GetNuFlavPDG, GetParentPDG, and GetXSecName. Each of these take an integer meant to be the index of a given object in the appropriate parameter vector.

  std::cout << "The current detector is "    << params.GetDetName(  params.GetCurrentDet())    << std::endl;
  std::cout << "The neutrino flavor PDG is " << params.GetNuFlavPDG(params.GetCurrentNuFlav()) << std::endl;
  std::cout << "The parent species PDG is "  << params.GetParentPDG(params.GetCurrentParent()) << std::endl;
  std::cout << "The cross section is "       << params.GetXSecName( params.GetCurrentXSec())   << std::endl;

A particular NuFlav and Detector object can be accessed using GetNuFlav and GetDetector. Since fields cannot be changed in these objects (with the one exception in Detector), this is only useful to access some of the other class member functions.

  NuFlav   currentNuFlavCopy = params.GetNuFlav(  params.GetCurrentNuFlav());
  Detector currentDetCopy    = params.GetDetector(paramsGetCurrentDet());

Returning to the master index, the user can access the maximum value of the master index using MaxMaster. This function can be called with or without an integer input. Without the integer input, the output will be the actual maximum value plus one, much like the std::vector::size function returns the maximum index of the vector plus one. By adding an integer input, the output will be the maximum index (plus one) for a particular detector, which is possible because the set of master indices that correspond to a particular detector are all grouped together by Parameters. The integer input, then, corresponds to a particular detector index.

  std::cout << "There are " << params.MaxMaster() << " unique sets of parameters in this object." << std::endl;
  std::cout << "There are " << params.MaxMaster(0) << " unique sets of parameters per detector." << std::endl;

If the user needs to loop over all parameters, the user should use the following method.

  for(const auto& index: params) {
    std::cout << "Flavor Index: " << params.GetCurrentNuFlav() << ", ";
    std::cout << "Parent Index: " << params.GetCurrentParent() << ", ";
    std::cout << "XSec Index: "   << params.GetCurrentXSec()   << ", ";
    std::cout << "Det Index: "    << params.GetCurentDet()     << std::endl;