SQLamarr
The stand-alone ultra-fast simulation option for the LHCb experiment
PVFinder.cpp
1 // (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration.
2 //
3 // This software is distributed under the terms of the GNU General Public
4 // Licence version 3 (GPL Version 3), copied verbatim in the file "LICENCE".
5 //
6 // In applying this licence, CERN does not waive the privileges and immunities
7 // granted to it by virtue of its status as an Intergovernmental Organization
8 // or submit itself to any jurisdiction.
9 
10 
11 #include "SQLamarr/PVFinder.h"
12 #include "SQLamarr/preprocessor_symbols.h"
13 #include <iostream>
14 
15 namespace SQLamarr
16 {
17  PVFinder::PVFinder (SQLite3DB& db, int signal_status_code)
18  : BaseSqlInterface(db)
19  , m_signal_status_code (signal_status_code)
20  {}
21 
22  void PVFinder::execute(void)
23  {
24  sqlite3_stmt* make_pv_from_signal = get_statement("make_pv_from_signal", R"(
25  WITH noPV_events
26  AS (
27  SELECT genevent_id
28  FROM GenVertices
29  GROUP BY genevent_id
30  HAVING
31  SUM(is_primary) = 0
32  ),
33  signal_root
34  AS
35  (
36  SELECT
37  genevent_id,
38  FIRST_VALUE(production_vertex)
39  OVER (PARTITION BY genevent_id ORDER BY hepmc_id ASC) AS root_vtx
40  FROM GenParticles
41  WHERE status==?
42  GROUP BY genevent_id
43  ),
44  selected_vertices
45  AS
46  (
47  SELECT genvertex_id
48  FROM GenVertices AS v
49  INNER JOIN noPV_events AS pv ON v.genevent_id = pv.genevent_id
50  INNER JOIN signal_root AS p ON p.root_vtx = v.genvertex_id
51  )
52  UPDATE GenVertices
53  SET
54  is_primary = TRUE
55  WHERE EXISTS (
56  SELECT NULL FROM selected_vertices
57  WHERE selected_vertices.genvertex_id = GenVertices.genvertex_id
58  );
59  )");
60 
61  sqlite3_stmt* make_pv_from_barcode = get_statement("make_pv_from_barcode", R"(
62  WITH noPV_events
63  AS (
64  SELECT genevent_id
65  FROM GenVertices
66  GROUP BY genevent_id
67  HAVING
68  SUM(is_primary) = 0
69  ),
70  signal_root
71  AS
72  (
73  SELECT
74  genevent_id,
75  FIRST_VALUE(production_vertex)
76  OVER (PARTITION BY genevent_id ORDER BY hepmc_id ASC) AS root_vtx
77  FROM GenParticles
78  GROUP BY genevent_id
79  ),
80  selected_vertices
81  AS
82  (
83  SELECT genvertex_id
84  FROM GenVertices AS v
85  INNER JOIN noPV_events AS pv ON v.genevent_id = pv.genevent_id
86  INNER JOIN signal_root AS p ON p.root_vtx = v.genvertex_id
87  )
88  UPDATE GenVertices
89  SET
90  is_primary = TRUE
91  WHERE EXISTS (
92  SELECT NULL FROM selected_vertices
93  WHERE selected_vertices.genvertex_id = GenVertices.genvertex_id
94  );
95  )");
96 
97 
98  sqlite3_stmt* import_pv = get_statement("import_pv", R"(
99  INSERT INTO MCVertices (
100  genvertex_id, genevent_id,
101  status, is_primary,
102  t, x, y, z
103  )
104  SELECT
105  v.genvertex_id, v.genevent_id,
106  v.status, v.is_primary,
107  v.t + e.t,
108  v.x + e.x,
109  v.y + e.y,
110  v.z + e.z
111  FROM GenVertices AS v
112  INNER JOIN GenEvents AS e ON e.genevent_id = v.genevent_id
113  WHERE
114  v.is_primary == TRUE
115  GROUP BY v.genevent_id
116  HAVING
117  v.hepmc_id == MAX(v.hepmc_id);
118  )");
119 
120 
121  sqlite3_stmt* count_missing_PVs = get_statement("count_missing_PVs", R"(
122  SELECT COUNT(genevent_id)
123  FROM GenVertices
124  GROUP BY genevent_id
125  HAVING
126  SUM(is_primary) = 0
127  )");
128 
129  exec_stmt(count_missing_PVs);
130  if (sqlite3_column_int(count_missing_PVs, 0))
131  {
132  sqlite3_bind_int(make_pv_from_signal, 1, m_signal_status_code);
133  exec_stmt(make_pv_from_signal);
134  }
135 
136  sqlite3_reset(count_missing_PVs);
137 
138  if (sqlite3_column_int(count_missing_PVs, 0))
139  exec_stmt(make_pv_from_barcode);
140 
141  exec_stmt(import_pv);
142 
143  }
144 }
Abstract interface with helper functions to access an SQLite DB.
sqlite3_stmt * get_statement(const std::string &name, const std::string &query)
Creates or retrieve from cache a statement.
bool exec_stmt(sqlite3_stmt *)
Execute a statement, possibly throwing an exception on failure.
PVFinder(SQLite3DB &db, int signal_status_code=889)
Constructor, with configurable signal status code.
Definition: PVFinder.cpp:17
void execute() override
Execute the algorithm.
Definition: PVFinder.cpp:22
A database connection handler easying sharing the DB between C++ and Python.
Definition: db_functions.py:24