BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
prerun_create.C
Go to the documentation of this file.
1// convert a datetime string in the SQL format ("yyyy-mm-dd hh:mm:ss") to TDatime
2bool parse_datetime(TString datetime_string, TDatime& datetime)
3{
4 TPRegexp re_datetime("^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$");
5 datetime_string = datetime_string.Strip(TString::kBoth);
6 if (!re_datetime.MatchB(datetime_string)) {
7 cout << "ERROR: wrong datetime format (\"yyyy-mm-dd hh:mm:ss\" is expected): " << datetime_string << endl;
8 return false;
9 }
10 datetime.Set(datetime_string.Data());
11 return true;
12}
13
14// creating new period/session with the given time interval
15// if the period already exists (isPeriodExists) then its start and end times are changed to the given ones
16int create_run_period(int period_number, TDatime start_datetime, TDatime end_datetime, bool isPeriodExists)
17{
18 if (!isPeriodExists) {
19 UniRunPeriod* pPeriod = UniRunPeriod::CreateRunPeriod(period_number, start_datetime, &end_datetime);
20 if (pPeriod == nullptr) {
21 cout << "ERROR: creating the run period " << period_number << " failed" << endl;
22 return -1;
23 }
24 cout << "The run period " << period_number << " was created: " << start_datetime.AsSQLString() << " - "
25 << end_datetime.AsSQLString() << endl;
26 delete pPeriod;
27 return 0;
28 }
29
30 cout << "WARNING: the run period " << period_number
31 << " already exists, its start and end times will be set to the given ones" << endl;
32 UniRunPeriod* pPeriod = UniRunPeriod::GetRunPeriod(period_number);
33 if (pPeriod == nullptr) {
34 cout << "ERROR: getting the run period " << period_number << " failed" << endl;
35 return -2;
36 }
37 if ((pPeriod->SetStartDatetime(start_datetime) != 0) || (pPeriod->SetEndDatetime(&end_datetime) != 0)) {
38 cout << "ERROR: updating start and end times of the run period " << period_number << " failed" << endl;
39 delete pPeriod;
40 return -3;
41 }
42 delete pPeriod;
43
44 return 0;
45}
46
47// creating fictitious run (without beam, target and events) if absent for parameter validity range
48int create_fictitious_run(int period_number, int run_number, TDatime start_datetime, TDatime end_datetime)
49{
50 int run_exists = UniRun::CheckRunExists(period_number, run_number);
51 if (run_exists < 0) {
52 cout << "ERROR: checking existence of the run " << period_number << ":" << run_number << " failed" << endl;
53 return -1;
54 }
55 if (run_exists > 0) {
56 cout << "WARNING: the run " << period_number << ":" << run_number << " already exists, it is skipped" << endl;
57 return 0;
58 }
59
60 // run type 0 is the same as for the runs automatically created on writing raw file metadata
61 UniRun* pRun = UniRun::CreateRun(period_number, run_number, 0, start_datetime, &end_datetime, "", "", "", nullptr,
62 nullptr, nullptr, 1);
63 if (pRun == nullptr) {
64 cout << "ERROR: creating the fictitious run " << period_number << ":" << run_number << " failed" << endl;
65 return -2;
66 }
67 cout << "The fictitious run " << period_number << ":" << run_number << " has been created" << endl;
68 delete pRun;
69
70 return 0;
71}
72
73// copying all detector parameter values valid for the previous run (prev_period:prev_run)
74// to the new validity range: period_number::start_run -> period_number::end_run
75// values having an active record overlapped with the new range (e.g. already copied before) are skipped
76// if isCopySingleRunValues is false then values valid only for one run (start = end, e.g. T0_SlewingCorr) are skipped,
77// because they are usually written run by run and a session-wide copy would block writing them for the new session
78int copy_detector_parameters(int period_number,
79 int start_run,
80 int end_run,
81 int prev_period,
82 int prev_run,
83 bool isCopySingleRunValues = false)
84{
86 if (connDb == nullptr) {
87 cout << "ERROR: connection to the UniConDa database failed" << endl;
88 return -1;
89 }
90
91 TSQLServer* db_server = connDb->GetSQLServer();
92 TString sql_source =
93 TString::Format("from detector_parameter dp join parameter_ p on dp.parameter_id = p.parameter_id "
94 "where dp.expiry_date is null "
95 // the value is valid for the previous run
96 "and ((dp.start_period < %d) or ((dp.start_period = %d) and (dp.start_run <= %d))) "
97 "and ((dp.end_period > %d) or ((dp.end_period = %d) and (dp.end_run >= %d))) "
98 // no active value of the same parameter overlaps the new validity range
99 "and not exists (select 1 from detector_parameter np "
100 "where np.detector_name = dp.detector_name and np.parameter_id = dp.parameter_id "
101 "and np.value_key = dp.value_key and np.expiry_date is null "
102 "and not (((np.end_period < %d) or ((np.end_period = %d) and (np.end_run < %d))) or "
103 "((np.start_period > %d) or ((np.start_period = %d) and (np.start_run > %d))))) ",
104 prev_period, prev_period, prev_run, prev_period, prev_period, prev_run, period_number,
105 period_number, start_run, period_number, period_number, end_run);
106 if (!isCopySingleRunValues)
107 sql_source += "and not ((dp.start_period = dp.end_period) and (dp.start_run = dp.end_run)) ";
108
109 // print detector parameter values to be copied
110 TString sql = "select dp.detector_name, p.parameter_name, dp.value_key, dp.start_period, dp.start_run, "
111 "dp.end_period, dp.end_run, length(dp.parameter_value) "
112 + sql_source + "order by dp.detector_name, p.parameter_name, dp.value_key";
113 TSQLStatement* stmt = db_server->Statement(sql);
114
115 if (!stmt->Process()) {
116 cout << "ERROR: getting detector parameters valid for the previous run failed" << endl;
117 delete stmt;
118 delete connDb;
119 return -2;
120 }
121 stmt->StoreResult();
122
123 int value_count = 0;
124 while (stmt->NextResultRow()) {
125 if (value_count == 0)
126 cout << "Detector parameter values to be copied to " << period_number << ":" << start_run << " - "
127 << period_number << ":" << end_run << endl;
128 cout << " " << stmt->GetString(0) << " : " << stmt->GetString(1) << " (key " << stmt->GetInt(2) << ", "
129 << stmt->GetInt(3) << ":" << stmt->GetInt(4) << " - " << stmt->GetInt(5) << ":" << stmt->GetInt(6) << ", "
130 << stmt->GetLong64(7) << " bytes)" << endl;
131 value_count++;
132 }
133 delete stmt;
134
135 if (value_count == 0) {
136 cout << "WARNING: there are no detector parameter values to be copied from the run " << prev_period << ":"
137 << prev_run << endl;
138 delete connDb;
139 return 0;
140 }
141
142 // copy the parameter values on the database side to avoid transferring large binary values
143 sql = TString::Format(
144 "insert into detector_parameter "
145 "(detector_name, parameter_id, start_period, start_run, end_period, end_run, value_key, parameter_value) "
146 "select dp.detector_name, dp.parameter_id, %d, %d, %d, %d, dp.value_key, dp.parameter_value ",
147 period_number, start_run, period_number, end_run)
148 + sql_source;
149 stmt = db_server->Statement(sql);
150
151 // write new parameter values to the database
152 if (!stmt->Process()) {
153 cout << "ERROR: copying detector parameters to the new period failed" << endl;
154 delete stmt;
155 delete connDb;
156 return -3;
157 }
158 cout << "Detector parameter values copied: " << stmt->GetNumAffectedRows() << endl;
159
160 delete stmt;
161 delete connDb;
162
163 return 0;
164}
165
166/**
167 * Main pre-run procedure to prepare metadata parameters for a new Run:
168 * 1. create the new period with the given time interval ("yyyy-mm-dd hh:mm:ss")
169 * 2. create fictitious runs with start_run and end_run numbers for the period
170 * 3. copy all detector parameter values valid for the last run before the period to
171 * period_number:start_run - period_number:end_run
172 * The fictitious run range is corrected to the real first and last runs after the session by postrun_update.C
173 *
174 * If the period already exists then nothing is changed and the macro exits (returns 1),
175 * unless isUpdateExistingPeriod is true: then the period times are set to the given ones,
176 * absent fictitious runs are created and absent parameter values are copied
177 *
178 * example:
179 * root -b -q 'prerun_create.C(10, "2026-10-01 00:00:00", "2027-04-01 00:00:00", 1, 100000)'
180 **/
181int prerun_create(int period_number,
182 TString start_datetime,
183 TString end_datetime,
184 int start_run = 1,
185 int end_run = 100000,
186 bool isCopySingleRunValues = false,
187 bool isUpdateExistingPeriod = false)
188{
189 TDatime period_start, period_end;
190 if (!parse_datetime(start_datetime, period_start) || !parse_datetime(end_datetime, period_end))
191 return -1;
192 if (period_start.Convert() >= period_end.Convert()) {
193 cout << "ERROR: start time of the period must be less than its end time" << endl;
194 return -1;
195 }
196 if (start_run >= end_run) {
197 cout << "ERROR: start run number must be less than the end run number" << endl;
198 return -1;
199 }
200
201 // exit without any changes if the period already exists, unless it is allowed to update the existing period
202 int period_exists = UniRunPeriod::CheckRunPeriodExists(period_number);
203 if (period_exists < 0) {
204 cout << "ERROR: checking existence of the run period " << period_number << " failed" << endl;
205 return -2;
206 }
207 if ((period_exists > 0) && !isUpdateExistingPeriod) {
208 cout << "WARNING: the run period " << period_number << " already exists, nothing is changed. "
209 << "Set isUpdateExistingPeriod to true to update the existing period" << endl;
210 return 1;
211 }
212
213 // find the previous run whose parameter values are copied to the new period (before creating fictitious runs)
214 int prev_period = period_number, prev_run = start_run;
215 if (UniRun::FindPreviousRun(prev_period, prev_run) != 0) {
216 cout << "ERROR: no previous run was found to copy parameters for the period " << period_number << endl;
217 return -3;
218 }
219 cout << "Detector parameters valid for the run " << prev_period << ":" << prev_run << " will be copied" << endl;
220
221 if (create_run_period(period_number, period_start, period_end, period_exists > 0) != 0)
222 return -4;
223
224 if (create_fictitious_run(period_number, start_run, period_start, period_start) != 0)
225 return -5;
226 if (create_fictitious_run(period_number, end_run, period_end, period_end) != 0)
227 return -5;
228
229 if (copy_detector_parameters(period_number, start_run, end_run, prev_period, prev_run, isCopySingleRunValues) != 0)
230 return -6;
231
232 return 0;
233}
const char * AsSQLString() const
void Set()
UInt_t Convert(Bool_t toGMT=kFALSE) const
Bool_t MatchB(const TString &s, const TString &mods="", Int_t start=0, Int_t nMaxMatch=10)
virtual TSQLStatement * Statement(const char *, Int_t=100)
virtual const char * GetString(Int_t)
virtual Bool_t NextResultRow()=0
virtual Int_t GetNumAffectedRows()
virtual Int_t GetInt(Int_t)
virtual Long64_t GetLong64(Int_t)
virtual Bool_t Process()=0
virtual Bool_t StoreResult()=0
TSubString Strip(EStripType s=kTrailing, char c=' ') const
const char * Data() const
static TString Format(const char *fmt,...)
static UniConnection * Open()
TSQLServer * GetSQLServer()
UniRunPeriod.h Class for the table: run_period.
static UniRunPeriod * GetRunPeriod(int period_number)
get run period from the database
int SetEndDatetime(TDatime *end_datetime)
set end datetime of the current run period
static int CheckRunPeriodExists(int period_number)
check run period exists in the database: 1- true, 0 - false, <0 - database operation error
int SetStartDatetime(TDatime start_datetime)
set start datetime of the current run period
static UniRunPeriod * CreateRunPeriod(int period_number, TDatime start_datetime, TDatime *end_datetime)
add new run period to the database
UniRun.h Class for the table: run_.
Definition UniRun.h:21
static UniRun * CreateRun(int period_number, int run_number, int run_type, TDatime start_datetime, TDatime *end_datetime, TString beam_particle, TString target_particle, double *energy, double *field_voltage, int *event_count, int run_quality)
add new run to the database
Definition UniRun.cxx:62
static int FindPreviousRun(int &period_number, int &run_number)
get number of the closest run below the given one or return the latest run in the database if period_...
Definition UniRun.cxx:1187
static int CheckRunExists(int period_number, int run_number)
check run exists in the database: 1- true, 0 - false, <0 - database operation error
Definition UniRun.cxx:241
int create_run_period(int period_number, TDatime start_datetime, TDatime end_datetime, bool isPeriodExists)
int copy_detector_parameters(int period_number, int start_run, int end_run, int prev_period, int prev_run, bool isCopySingleRunValues=false)
int create_fictitious_run(int period_number, int run_number, TDatime start_datetime, TDatime end_datetime)
int prerun_create(int period_number, TString start_datetime, TString end_datetime, int start_run=1, int end_run=100000, bool isCopySingleRunValues=false, bool isUpdateExistingPeriod=false)
Main pre-run procedure to prepare metadata parameters for a new Run:
bool parse_datetime(TString datetime_string, TDatime &datetime)