~mdrews/maus/my-branch

« back to all changes in this revision

Viewing changes to src/output/OutputCppRoot/OutputCppRoot.cc

  • Committer: Durga Rajaram
  • Date: 2013-10-17 14:45:06 UTC
  • mfrom: (659.1.76 rc)
  • Revision ID: durga@fnal.gov-20131017144506-orvzitqqdbj08ohy
Tags: MAUS-v0.7.3
MAUS-v0.7.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 *
16
16
 */
17
17
 
 
18
#include <sys/stat.h>
 
19
#include <sys/types.h>
 
20
 
 
21
#include <algorithm>
 
22
 
18
23
#include "src/legacy/Interface/Squeal.hh"
19
24
 
20
25
#include "src/common_cpp/Utils/JsonWrapper.hh"
39
44
 
40
45
namespace MAUS {
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) {
43
49
}
44
50
 
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");
55
 
    _outfile->close();
 
59
    if (_fname == "") {
 
60
        throw(Squeal(
 
61
          Squeal::recoverable,
 
62
          "output_root_file_name is empty",
 
63
          "OutputCppRoot::birth"
 
64
        ));
 
65
    }
 
66
    std::string mode = JsonWrapper::GetProperty(datacards,
 
67
                  "output_root_file_mode", JsonWrapper::stringValue).asString();
 
68
    if (mode == "one_big_file") {
 
69
        _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;
 
74
    } else {
 
75
        throw(Squeal(
 
76
          Squeal::recoverable,
 
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"
 
82
        ));
 
83
    }
 
84
    _end_of_run_dir = JsonWrapper::GetProperty(
 
85
                                          datacards,
 
86
                                          "end_of_run_output_root_directory",
 
87
                                          JsonWrapper::stringValue).asString();
56
88
  } catch(...) {
57
89
    death();
58
90
    throw;
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 == "")
 
100
        return false;
 
101
 
 
102
    ConverterT conv;
 
103
    data_cpp = conv.convert(&data_json);
 
104
    check_file_exists(data_cpp);
67
105
    if (_outfile == NULL) {
68
 
        throw(Squeal(Squeal(
 
106
        throw(Squeal(
69
107
          Squeal::recoverable,
70
108
          "OutputCppRoot was not initialised properly",
71
109
          "OutputCppRoot::write_event"
72
 
        )));
 
110
        ));
73
111
    }
74
 
    if (branch_name == "")
75
 
        return false;
 
112
 
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();
80
 
        _outfile->open
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;
83
121
    }
84
122
    (*_outfile) << branchName(branch_name.c_str()) << data_cpp;
85
 
    ConverterT conv;
86
 
    data_cpp = conv.convert(&data_json);
 
123
 
87
124
    if (data_cpp->GetEvent() == NULL) {  // failed on conversion
88
125
        return false;
89
126
    }
149
186
    _outfile = NULL;  // deletes spill
150
187
  }
151
188
}
 
189
 
 
190
std::string OutputCppRoot::file_name(int run_number) {
 
191
    std::string run_numb_str = STLUtils::ToString(run_number);
 
192
    switch (_mode) {
 
193
        case one_big_file:
 
194
            return _fname;
 
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;
 
203
            }
 
204
            }
 
205
        case end_of_run_file_per_run:
 
206
            return _end_of_run_dir+"/"+run_numb_str+"/"+_fname;
 
207
    }
 
208
    return "";
 
209
}
 
210
 
 
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
 
215
          return "./";
 
216
      } else {  // file.root -> file_1234.root
 
217
          return file.substr(0, slash);
 
218
      }
 
219
}
 
220
 
 
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);
 
225
    switch (_mode) {
 
226
        case one_big_file:
 
227
            if (_run_numbers.size() > 0)
 
228
                return;
 
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))
 
232
                return;
 
233
    }
 
234
    if (_outfile != NULL) {
 
235
        if (_outfile->is_open())
 
236
            _outfile->close();
 
237
        delete _outfile;
 
238
    }
 
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");
 
246
        }
 
247
    }
 
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);
 
255
}
 
256
 
 
257
template <>
 
258
int OutputCppRoot::run_number(MAUSEvent<Spill>* data_cpp) {
 
259
    return data_cpp->GetEvent()->GetRunNumber();
 
260
}
 
261
 
 
262
template <>
 
263
int OutputCppRoot::run_number(MAUSEvent<RunHeader>* data_cpp) {
 
264
    return data_cpp->GetEvent()->GetRunNumber();
 
265
}
 
266
 
 
267
template <>
 
268
int OutputCppRoot::run_number(MAUSEvent<RunFooter>* data_cpp) {
 
269
    return data_cpp->GetEvent()->GetRunNumber();
 
270
}
 
271
 
 
272
template <>
 
273
int OutputCppRoot::run_number(MAUSEvent<JobHeader>* data_cpp) {
 
274
    return 0;
 
275
}
 
276
 
 
277
template <>
 
278
int OutputCppRoot::run_number(MAUSEvent<JobFooter>* data_cpp) {
 
279
    return 0;
 
280
}
152
281
}
153
282