source: trunk/MagicSoft/Mars/mbase/MWriteAsciiFile.cc@ 1348

Last change on this file since 1348 was 1348, checked in by tbretz, 22 years ago
*** empty log message ***
  • Property svn:executable set to *
File size: 10.3 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz 06/2001 <mailto:tbretz@uni-sw.gwdg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2002
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26// //
27// MWriteAsciiFile //
28// //
29// If you want to store a single container into an Ascii file you have //
30// to use this class. You must know the name of the file you wanne write //
31// (you should know it) and the name of the container you want to write. //
32// This can be the name of the class or a given name, which identifies //
33// the container in a parameter container list (MParList). //
34// The container is written to the ascii file if its ReadyToSave flag is //
35// set (MParContainer) //
36// //
37// You can write more than one container in one line of the file, see //
38// AddContainer. //
39// //
40// You can also write single data members of a container (like fWidth //
41// of MHillas). For more details see AddContainer. Make sure, that a //
42// getter method for the data member exist. The name of the method //
43// must be the same than the data member itself, but the f must be //
44// replaced by a Get. //
45// //
46/////////////////////////////////////////////////////////////////////////////
47
48#include "MWriteAsciiFile.h"
49
50#include <fstream.h>
51
52#include <TClass.h> // IsA
53#include <TMethodCall.h> // TMethodCall, AsciiWrite
54
55#include "MDataList.h" // MDataList
56#include "MDataChain.h" // MDataChain
57#include "MDataValue.h" // MDataValue
58#include "MDataMember.h" // MDataMember
59
60#include "MLog.h"
61#include "MLogManip.h"
62
63#include "MParList.h"
64
65ClassImp(MWriteAsciiFile);
66
67// --------------------------------------------------------------------------
68//
69// Init. Replaces the same code used in all constructors.
70//
71void MWriteAsciiFile::Init(const char *filename, const char *name, const char *title)
72{
73 fName = name ? name : "MWriteAsciiFile";
74 fTitle = title ? title : "Task to write one container to an ascii file";
75
76 fNameFile = filename;
77
78 fOut = new ofstream(fNameFile);
79}
80
81// --------------------------------------------------------------------------
82//
83// Specify the name of the ascii output file 'filename' and the name
84// of the container you want to write. (Normally this is the name
85// of the class (eg. MHillas) but it can also be a different name which
86// identifies the container in the parameter list.
87// Because you cannot write more than one container there is no Add-function
88// like in MWriteRootFile.
89//
90// For Example: MWriteAsciiFile("file.txt", "MHillas");
91//
92MWriteAsciiFile::MWriteAsciiFile(const char *filename, const char *contname,
93 const char *name, const char *title)
94{
95 Init(filename, name, title);
96
97 if (contname)
98 AddContainer(contname);
99}
100
101// --------------------------------------------------------------------------
102//
103// Specify a the name of the ascii output file 'filename' and a pointer to
104// the container you want to write.
105// Because you cannot write more than one container there is no Add-function
106// like in MWriteRootFile.
107//
108// For Example: MHillas hillas;
109// MWriteAsciiFile("file.txt", &hillas);
110//
111//
112MWriteAsciiFile::MWriteAsciiFile(const char *filename, MParContainer *cont,
113 const char *name, const char *title)
114{
115 Init(filename, name, title);
116
117 if (cont)
118 AddContainer(cont);
119}
120
121// --------------------------------------------------------------------------
122//
123// Destructor. Delete the output file if necessary (it is closed
124// automatically by its destructor.
125//
126MWriteAsciiFile::~MWriteAsciiFile()
127{
128 fAutoDel.SetOwner();
129 delete fOut;
130}
131
132// --------------------------------------------------------------------------
133//
134// Return open state of the file
135//
136Bool_t MWriteAsciiFile::IsFileOpen() const
137{
138 return (bool)(*fOut);
139}
140
141// --------------------------------------------------------------------------
142//
143// Add a rule to be written as a column to the ascii file.
144// For more information about rules see MDataChain.
145//
146void MWriteAsciiFile::AddRule(const char *rule)
147{
148 MDataChain *chain = new MDataChain(rule);
149 fList.Add(chain);
150}
151
152// --------------------------------------------------------------------------
153//
154// Add another container (by pointer) to be written to the ascii file.
155// The container will be output one after each other in one line.
156// If you want to write only one data member of the container
157// specify the name of the data member (eg. fAlpha) Make sure,
158// that a "GetteMethod" for this data type exists (strip the f and
159// replace it by Get)
160// If you specify a single data member you can add a scale-factor which
161// is (in case of the data member being a floating point value) multiplied
162// with the data member value. This is usefull if you are want to
163// change the scale (unit) of a data member for writing (eg.
164// writing degrees for the hillas parameters instead of the internally
165// used millimeters)
166//
167void MWriteAsciiFile::AddContainer(MParContainer *cont, const TString member, Double_t scale)
168{
169 if (member.IsNull())
170 {
171 fList.Add(cont);
172 return;
173 }
174
175 MData *data = new MDataMember(cont, member);
176
177 if (scale!=1)
178 {
179 MDataList *list = new MDataList('*');
180 MDataValue *val = new MDataValue(scale);
181
182 list->SetOwner();
183 list->AddToList(data);
184 list->AddToList(val);
185
186 data = list;
187 }
188 fList.Add(data);
189 fAutoDel.Add(data);
190}
191
192// --------------------------------------------------------------------------
193//
194// Add another container (by name) to be written to the ascii file.
195// The container will be output one after each other in one line.
196// If you want to write only one data member of the container
197// specify the name of the data member (eg. fAlpha) Make sure,
198// that a "GetteMethod" for this data type exists (strip the f and
199// replace it by Get)
200// If you specify a single data member you can add a scale-factor which
201// is (in case of the data member being a floating point value) multiplied
202// with the data member value. This is usefull if you are want to
203// change the scale (unit) of a data member for writing (eg.
204// writing degrees for the hillas parameters instead of the internally
205// used millimeters)
206//
207void MWriteAsciiFile::AddContainer(const TString cont, const TString member, Double_t scale)
208{
209 if (member.IsNull())
210 {
211 TNamed *name = new TNamed(cont, cont);
212 fList.Add(name);
213 fAutoDel.Add(name);
214 return;
215 }
216
217 MData *data = new MDataMember(Form("%s.%s", (const char*)cont, (const char*)member));
218 if (scale!=1)
219 {
220 MDataList *list = new MDataList('*');
221 MDataValue *val = new MDataValue(scale);
222
223 list->SetOwner();
224 list->AddToList(data);
225 list->AddToList(val);
226
227 data = list;
228 }
229 fList.Add(data);
230 fAutoDel.Add(data);
231}
232
233// --------------------------------------------------------------------------
234//
235// Tries to get all containers from the ParList which were given by name
236// adds them to the list of pointers to the container which should be
237// written to the ascii file.
238//
239Bool_t MWriteAsciiFile::GetContainer(MParList *plist)
240{
241 TObject *obj=NULL;
242
243 TIter Next(&fList);
244 while ((obj=Next()))
245 {
246 //
247 // MData is the highest class in the inheritance tree
248 //
249 if (obj->IsA()->InheritsFrom(MData::Class()))
250 {
251 if (!((MData*)obj)->PreProcess(plist))
252 return kFALSE;
253 continue;
254 }
255
256 //
257 // MParContainer is the next class in the inheritance tree
258 //
259 if (obj->IsA()->InheritsFrom(MParContainer::Class()))
260 continue;
261
262 //
263 // It is neither a MData nor a MParContainer, it must be a TNamed
264 //
265 TObject *o = plist->FindObject(obj->GetName());
266 if (!o)
267 return kFALSE;
268
269 fList[fList.IndexOf(obj)] = o;
270 }
271 return kTRUE;
272}
273
274// --------------------------------------------------------------------------
275//
276// Check if the containers are ready for writing. If so write them.
277// The containers are written in one line, one after each other.
278// If not all containers are written (because of the IsReadyToSave-flag)
279// a warning message is print.
280//
281void MWriteAsciiFile::CheckAndWrite() const
282{
283 Bool_t written = kFALSE;
284
285 MParContainer *obj = NULL;
286
287 Int_t num = fList.GetEntries();
288
289 *fLog << all << "CHECK&WRITE " << num << endl;
290
291 TIter Next(&fList);
292 while ((obj=(MParContainer*)Next()))
293 {
294 *fLog << all << endl << obj->IsA()->GetName() << ": 0..." << flush;
295
296 if (!obj->IsReadyToSave())
297 continue;
298
299 *fLog << all << "1..." << flush;
300
301 if (!obj->AsciiWrite(*fOut))
302 continue;
303
304 *fLog << all << "2..." << flush;
305
306 written = kTRUE;
307
308 num--;
309 }
310
311 if (!written)
312 return;
313
314 *fOut << endl;
315
316 if (num!=0)
317 *fLog << warn << "Warning - given number of objects doesn't fit number of written objects." << endl;
318}
319
Note: See TracBrowser for help on using the repository browser.