41
46
OutputCppRoot::OutputCppRoot() : OutputBase<std::string>("OutputCppRoot"),
42
_outfile(NULL), _fname(""), _outfile_branch("") {
47
_outfile(NULL), _fname(""), _end_of_run_dir("./"), _outfile_branch(""),
48
_run_numbers(), _mode(one_big_file) {
45
51
void OutputCppRoot::_birth(const std::string& json_datacards) {
50
56
Json::Value datacards = JsonWrapper::StringToJson(json_datacards);
51
57
_fname = JsonWrapper::GetProperty(datacards,
52
58
"output_root_file_name", JsonWrapper::stringValue).asString();
53
// Setup output stream
54
_outfile = new orstream(_fname.c_str(), "Spill", "MAUS output data", "RECREATE");
62
"output_root_file_name is empty",
63
"OutputCppRoot::birth"
66
std::string mode = JsonWrapper::GetProperty(datacards,
67
"output_root_file_mode", JsonWrapper::stringValue).asString();
68
if (mode == "one_big_file") {
70
} else if (mode == "one_file_per_run") {
71
_mode = one_file_per_run;
72
} else if (mode == "end_of_run_file_per_run") {
73
_mode = end_of_run_file_per_run;
77
"output_root_file_name '"+mode+"' is not valid; should be one of\n"+
78
std::string(" one_big_file\n")+
79
std::string(" one_file_per_run\n")+
80
std::string(" end_of_run_file_per_run\n"),
81
"OutputCppRoot::birth"
84
_end_of_run_dir = JsonWrapper::GetProperty(
86
"end_of_run_output_root_directory",
87
JsonWrapper::stringValue).asString();
64
96
const Json::Value& data_json,
65
97
std::string branch_name) {
66
98
// watch for double frees (does close() delete data_cpp?)
99
if (branch_name == "")
103
data_cpp = conv.convert(&data_json);
104
check_file_exists(data_cpp);
67
105
if (_outfile == NULL) {
69
107
Squeal::recoverable,
70
108
"OutputCppRoot was not initialised properly",
71
109
"OutputCppRoot::write_event"
74
if (branch_name == "")
76
113
std::string data_type = data_cpp->GetEventType();
77
114
if (_outfile_branch != data_type) {
78
115
if (_outfile->is_open())
79
116
_outfile->close();
81
(_fname.c_str(), data_type.c_str(), "MAUS output data", "UPDATE");
117
int run = run_number(data_cpp);
118
_outfile->open(file_name(run).c_str(), data_type.c_str(),
119
"MAUS output data", "UPDATE");
82
120
_outfile_branch = data_type;
84
122
(*_outfile) << branchName(branch_name.c_str()) << data_cpp;
86
data_cpp = conv.convert(&data_json);
87
124
if (data_cpp->GetEvent() == NULL) { // failed on conversion
149
186
_outfile = NULL; // deletes spill
190
std::string OutputCppRoot::file_name(int run_number) {
191
std::string run_numb_str = STLUtils::ToString(run_number);
195
case one_file_per_run: {
196
size_t dot = _fname.find_last_of('.');
197
if (dot == std::string::npos) { // file -> file_1234
198
return _fname+"_"+run_numb_str;
199
} else { // file.root -> file_1234.root
200
std::string one = _fname.substr(0, dot);
201
std::string two = _fname.substr(dot, _fname.size() - dot);
202
return one+"_"+run_numb_str+two;
205
case end_of_run_file_per_run:
206
return _end_of_run_dir+"/"+run_numb_str+"/"+_fname;
211
std::string OutputCppRoot::dir_name(int run_number) {
212
std::string file = file_name(run_number);
213
size_t slash = file.find_last_of('/');
214
if (slash == std::string::npos) { // file -> file_1234
216
} else { // file.root -> file_1234.root
217
return file.substr(0, slash);
221
template <class DataT>
222
void OutputCppRoot::check_file_exists(DataT data_cpp) {
223
std::string event = data_cpp->GetEventType();
224
int run = run_number(data_cpp);
227
if (_run_numbers.size() > 0)
229
case one_file_per_run:
230
case end_of_run_file_per_run:
231
if (std::binary_search(_run_numbers.begin(), _run_numbers.end(), run))
234
if (_outfile != NULL) {
235
if (_outfile->is_open())
239
struct stat attributes;
240
std::string dir = dir_name(run);
241
if (stat(dir.c_str(), &attributes) < 0 || !S_ISDIR(attributes.st_mode)) {
242
// if stat fails, maybe the directory doesnt exists
243
if (mkdir(dir.c_str(), ACCESSPERMS) == -1) {
244
throw Squeal(Squeal::recoverable, "Failed to make directory "+dir,
245
"OutputCppRoot::check_file_exists");
248
// S_ISDIR(attributes.st_mode) - returns True if it's a directory...
249
_outfile = new orstream(file_name(run).c_str(),
250
data_cpp->GetEventType().c_str(),
251
"MAUS output data", "RECREATE");
252
_outfile_branch = data_cpp->GetEventType();
253
std::vector<int>::iterator it = std::upper_bound(_run_numbers.begin(), _run_numbers.end(), run);
254
_run_numbers.insert(it, run);
258
int OutputCppRoot::run_number(MAUSEvent<Spill>* data_cpp) {
259
return data_cpp->GetEvent()->GetRunNumber();
263
int OutputCppRoot::run_number(MAUSEvent<RunHeader>* data_cpp) {
264
return data_cpp->GetEvent()->GetRunNumber();
268
int OutputCppRoot::run_number(MAUSEvent<RunFooter>* data_cpp) {
269
return data_cpp->GetEvent()->GetRunNumber();
273
int OutputCppRoot::run_number(MAUSEvent<JobHeader>* data_cpp) {
278
int OutputCppRoot::run_number(MAUSEvent<JobFooter>* data_cpp) {