Step 2: Generate data samples¶
Warning
The pycompwa is no longer maintained. Use the ComPWA packages QRules, AmpForm, and TensorWaves instead!
In this section, we will use the amplitude model that we created with the expert system to generate a data sample via hit & miss Monte Carlo. This requires us to work with the User Interface to ComPWA, the C++ back-end of pycompwa
.
2.1 Generate¶
In the previous step, we created an amplitude module and exported it as an XML file. We now need to go through a few steps to generate a phase space sample and a data sample for the decay \(J/\psi \rightarrow \gamma\pi^0\pi^0\):
Import the section of particle definitions that is embedded in the XML file.
Build a
Kinematics
object following the specifications of the dynamics in the XML model file (in this case, the helicity formalism). The second argument of this function is a particle list.The information in the
Kinematics
instance is sufficient for generating a phase space sample. This sample defines the space on which to evaluate the intensities of the amplitude model.For generating a data sample, you require an
Intensity
profile for this specific decay. You can construct such an object from the model XML file using theIntensityBuilderXML
. Because we want the intensities to be normalized, you have to pass the generated phase space sample as an argument to the intensity builder. Note that during the creation of theIntensity
object, theKinematics
instance is updated with the subsystems required for the decay topology.
Now all building blocks for generating our data sample are at hand and you can define a data sample of arbitrary size!
import pycompwa.ui as pwa # interface to ComPWA
2021-10-27 10:27:26,316 INFO [default] Logging to file disabled!
2021-10-27 10:27:26,316 [INFO] Log level: INFO
2021-10-27 10:27:26,316 [INFO] Current date and time: Wed Oct 27 10:27:26 2021
# specify kinematics
particle_list = pwa.read_particles("model.xml")
kinematics = pwa.create_helicity_kinematics("model.xml", particle_list)
# specify generators
generator = pwa.EvtGenGenerator(
kinematics.get_particle_state_transition_kinematics_info()
)
random_generator = pwa.StdUniformRealGenerator(12345)
# generate phase space sample
phsp_sample = pwa.generate_phsp(int(1e5), generator, random_generator)
# create intensity profile
intensity_builder = pwa.IntensityBuilderXML(
"model.xml", particle_list, kinematics, phsp_sample
)
intensity = intensity_builder.create_intensity()
# generate data
data_sample = pwa.generate(
int(1e4), kinematics, generator, intensity, random_generator
)
2021-10-27 10:27:26,709 [INFO] HelicityKinematics::HelicityKinematics() | Initialized kinematics for reaction ( J/psi )->( gamma[ID=2] pi0[ID=3] pi0[ID=4] )
Event position to final state ID mapping:
0: 2
1: 3
2: 4
2021-10-27 10:27:26,711 [INFO] Generating phase-space MC: [100000 events]
?25l
0.00min [ ---------- 0.00% ] 0.00min , end time: 10:27AM ?25h
?25l
0.00min [ ********** 100.00% ] 0.00min , end time: 10:27AM ?25h
2021-10-27 10:27:26,794 [INFO] Setting phase space sample weights...
2021-10-27 10:27:26,802 [INFO] Updating data container content...
2021-10-27 10:27:28,496 [INFO] Generating hit-and-miss sample: [10000 events]
?25l
0.00min [ ---------- 0.00% ] 0.00min , end time: 10:27AM ?25h
2021-10-27 10:27:29,082 [INFO] Tools::generate() | Error in HitMiss procedure: Maximum value of random number generation smaller then amplitude maximum! We raise the maximum to 9.92631 value and restart generation!
?25l
0.00min [ ---------- 0.00% ] 0.00min , end time: 10:27AM ?25h
2021-10-27 10:27:31,090 [INFO] Successfully generated 10000 with an efficiency of 0.0740741
?25l
0.03min [ ********** 100.00% ] 0.00min , end time: 10:27AM ?25h?25l
0.03min [ ********** 100.00% ] 0.00min , end time: 10:27AM ?25h
Note
pycompwa.ui
is the python interface to ComPWA’s C++ modules. It has four major important components for evaluating intensities:
The
EventCollection
class is simply an event-based list of four-momenta with a list of Particle IDs.The
Kinematics
class allows one to compute kinematic variables, like \((s,\theta,\phi)\) in the helicity formalism, from the momentum tuples in anEventCollection
.The
DataSet
class is the result when youconvert()
anEventCollection
. It is essentially a table of kinematic variables for each event in that original collection of four-momenta.The
Intensity
class allows one to compute an intensity (an absolute value) for each data point in theDataSet
. You do this computation with theevaluate()
method (see Step 4: Analyze results).
Hint
For more complicated data sample structures, see Importance sampling.
2.2 Exporting and importing¶
The pycompwa.ui
module allows you to export the data samples to two different file formats: ROOT files and ASCII files.
# to ROOT
pwa.write_root_data(data_sample, output_file="generated_data.root")
pwa.write_root_data(phsp_sample, output_file="generated_phsp.root")
# to ASCII
pwa.write_ascii_data(data_sample, output_file="generated_data.dat")
pwa.write_ascii_data(phsp_sample, output_file="generated_phsp.dat")
2021-10-27 10:27:31,265 [INFO] Root::writeData(): writing vector of 10000 events to file generated_data.root
2021-10-27 10:27:31,405 [INFO] Root::writeData(): writing vector of 100000 events to file generated_phsp.root
2021-10-27 10:27:31,999 [INFO] Logging to file disabled!
The syntax for importing parallels that:
imported_data = pwa.read_root_data(input_file="generated_data.root")
imported_phsp = pwa.read_ascii_data(input_file="generated_phsp.dat")
print("Imported data events:", len(imported_data.events))
print("Imported phsp events:", len(imported_phsp.events))
first_event = imported_data.events[0]
print("First data event:")
print(first_event.four_momenta)
print(first_event.weight)
Imported data events: 10000
Imported phsp events: 100000
First data event:
FourMomentumList[(-0.520903,0.885259,1.21872), (0.653672,-0.813022,1.46359), (-0.132769,-0.0722372,0.414596)]
1.0
Note that the ASCII (.dat
) files contain a header section that informs you about the final state of the file. You will have to prepend this section to the file yourself if you want to use an ASCII file that was exported from another framework.
with open("generated_data.dat") as f:
for _ in range(5):
print(f.readline()[:-1])
<header>
Pids: [22, 111, 111]
Order: px py pz E
Unit: GeV
</header>