Belle II Software development
DqmMemFile.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include "daq/dqm/DqmMemFile.h"
10#include <framework/pcore/MsgHandler.h>
11
12#include <TH1.h>
13#include <TKey.h>
14#include <TText.h>
15
16using namespace Belle2;
17using namespace std;
18
19// Constructor
20DqmMemFile::DqmMemFile(string name, const string& mode, int size)
21{
22 // Record parameters
23 m_size = size;
24 if (mode != "write" && mode != "WRITE")
25 m_writeMode = false;
26 else
27 m_writeMode = true;
28 m_name = name;
29 m_memfile = NULL;
30
31 // Allocate memory space for TMemFile
32 m_buf = (char*) new int[size];
33
34 // Allocate shared memory
35 m_shm = new DqmSharedMem((char*)name.c_str(), size, m_writeMode);
36
37 // Clear/Open TMemFile if write mode selected
38 // it will check write mode by itself!
39 if (ClearSharedMem() == 0) {
40 printf("DqmMemFile : TMemFile is opened in WRITE mode.\n");
41 } else {
42 printf("DqmMemFile : TMemFile is opend in READ mode.\n");
43 }
44}
45
46
47DqmMemFile::DqmMemFile(int shm_id, int sem_id, int size)
48{
49 // This defaults to read only access
50 // Record parameters
51 m_size = size;
52 m_writeMode = false;
53 m_name = "dqm_mem_file";
54 m_memfile = NULL;
55
56 // Allocate memory space for TMemFile
57 m_buf = (char*) new int[size];
58
59 // Allocate shared memory
60 m_shm = new DqmSharedMem(shm_id, sem_id);
61 printf("DqmMemFile : TMemFile is opend in READ mode.\n");
62}
63
64// Destructor
65DqmMemFile::~DqmMemFile()
66{
67 if (m_memfile != NULL)
68 delete m_memfile;
69 delete m_shm;
70 delete m_buf;
71}
72
73// Returns pointer to TMemFile
74TMemFile* DqmMemFile::GetMemFile()
75{
76 return m_memfile;
77}
78
79// Copy TMemFile contents to Shared Memory
80int DqmMemFile::UpdateSharedMem()
81{
82 if (!m_writeMode) return -1;
83 m_memfile->Write(0, TObject::kOverwrite);
84 m_shm->lock();
85 auto ret = m_memfile->CopyTo((char*)(m_shm->ptr()), m_memfile->GetSize());
86
87 FILE* fh = fopen(("/dev/shm/tmp_" + m_name).c_str(), "wb+");
88 if (fh) {
89 fwrite(m_shm->ptr(), 1, ret, fh);
90 fclose(fh);
91 if (rename(("/dev/shm/tmp_" + m_name).c_str(), ("/dev/shm/" + m_name).c_str())) {
92 perror("Rename dhm file failed ");
93 }
94 }
95
96 m_shm->unlock();
97 return 0;
98}
99
100int DqmMemFile::ClearSharedMem()
101{
102 if (!m_writeMode) return -1;
103 // Open TMemFile only if write mode selected
104
105 if (m_memfile != NULL) delete m_memfile;
106 m_memfile = new TMemFile(m_name.c_str(), m_buf, m_size * sizeof(int), "RECREATE");
107
108 m_shm->lock();
109 m_memfile->CopyTo((char*)(m_shm->ptr()), m_memfile->GetSize());
110 m_shm->unlock();
111
112 return 0;
113}
114
115TMemFile* DqmMemFile::LoadMemFile()
116{
117 if (m_writeMode) return NULL;
118
119 if (m_memfile != NULL) {
120 delete m_memfile;
121 }
122
123 m_shm->lock();
124 memcpy(m_buf, m_shm->ptr(), m_size * sizeof(int));
125 m_shm->unlock();
126 // m_memfile = new TMemFile ( m_name.c_str(), m_buf, m_size*sizeof(int), "RECREATE" );
127 m_memfile = new TMemFile(m_name.c_str(), m_buf, c_memFileSize);
128 return m_memfile;
129}
130
131// Copy Shared Memory to local and stream
132EvtMessage* DqmMemFile::StreamMemFile()
133{
134 TMemFile* memfile = LoadMemFile();
135 if (memfile == NULL) return NULL;
136 // memfile->ls();
137 // memfile->Print();
138 memfile->cd();
139 // gDirectory->ls();
140 // TList* keylist = memfile->GetListOfKeys();
141 // keylist->ls();
142 MsgHandler hdl(0);
143 int numobjs = 0;
144 // StreamHistograms ( memfile->GetDirectory(NULL), &hdl, numobjs );
145 StreamHistograms(gDirectory, &hdl, numobjs);
146 // printf ( "DqmMemFile::StreamMemFile : streamed %d histograms in EvtMessage\n", numobjs );
147 EvtMessage* msg = hdl.encode_msg(MSG_EVENT);
148 (msg->header())->reserved[0] = 0;
149 (msg->header())->reserved[1] = numobjs;
150 return msg;
151}
152
153int DqmMemFile::StreamHistograms(TDirectory* curdir, MsgHandler* msg, int& numobjs)
154{
155 TList* keylist = curdir->GetListOfKeys();
156 // keylist->ls();
157
158 TIter nextkey(keylist);
159 TKey* key = 0;
160 int nkeys [[maybe_unused]] = 0;
161 int nobjs [[maybe_unused]] = 0;
162 while ((key = (TKey*)nextkey())) {
163 nkeys++;
164 TObject* obj = curdir->FindObjectAny(key->GetName());
165 if (obj->IsA()->InheritsFrom("TH1")) {
166 TH1* h1 = (TH1*) obj;
167 // printf ( "Key = %s, entry = %f\n", key->GetName(), h1->GetEntries() );
168 msg->add(h1, h1->GetName());
169 nobjs++;
170 numobjs++;
171 } else if (obj->IsA()->InheritsFrom(TDirectory::Class())) {
172 // printf ( "New directory found %s, Go into subdir\n", obj->GetName() );
173 TDirectory* tdir = (TDirectory*) obj;
174 // m_msg->add(tdir, tdir->GetName());
175 TText subdir(0, 0, tdir->GetName());
176 msg->add(&subdir, "SUBDIR:" + string(obj->GetName())) ;
177 nobjs++;
178 numobjs++;
179 tdir->cd();
180 StreamHistograms(tdir, msg, numobjs);
181 TText command(0, 0, "COMMAND:EXIT");
182 msg->add(&command, "SUBDIR:EXIT");
183 nobjs++;
184 numobjs++;
185 curdir->cd();
186 }
187 }
188 return 0;
189}
190
191bool DqmMemFile::SaveToFile(std::string outfile)
192{
193 // we do not work on shared memory, thus can directly write w/o locking
194// m_memfile->Write(0, TObject::kOverwrite);
195// m_memfile->WriteToFile(outfile);
196
197 printf("dump to dqm file = %s\n", outfile.c_str());
198
199 TFile* dqmtfile = new TFile(outfile.c_str(), "RECREATE");
200
201 // Copy all histograms in TFile
202 TIter next(m_memfile->GetListOfKeys());
203 TKey* key = NULL;
204 while ((key = (TKey*)next())) {
205 TH1* hist = (TH1*)key->ReadObj();
206 // printf("HistTitle %s : entries = %f\n", hist->GetName(), hist->GetEntries());
207 hist->Write();
208 }
209
210 // Close TFile
211 dqmtfile->Write();
212 dqmtfile->Close();
213
214 delete dqmtfile;
215
216 return true;
217}
Class to manage streamed object.
Definition: EvtMessage.h:59
EvtHeader * header()
Get pointer to EvtHeader.
Definition: EvtMessage.cc:161
A class to encode/decode an EvtMessage.
Definition: MsgHandler.h:103
virtual void add(const TObject *, const std::string &name)
Add an object to be streamed.
Definition: MsgHandler.cc:46
Abstract base class for different kinds of events.
STL namespace.