source: trunk/MagicSoft/Mars/mfileio/MWriteAsciiFile.cc@ 1381

Last change on this file since 1381 was 1381, checked in by tbretz, 22 years ago
*** empty log message ***
File size: 10.0 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 <TMethodCall.h> // TMethodCall, AsciiWrite
53
54#include "MDataList.h" // MDataList
55#include "MDataChain.h" // MDataChain
56#include "MDataValue.h" // MDataValue
57#include "MDataMember.h" // MDataMember
58
59#include "MLog.h"
60#include "MLogManip.h"
61
62#include "MParList.h"
63
64ClassImp(MWriteAsciiFile);
65
66// --------------------------------------------------------------------------
67//
68// Init. Replaces the same code used in all constructors.
69//
70void MWriteAsciiFile::Init(const char *filename, const char *name, const char *title)
71{
72 fName = name ? name : "MWriteAsciiFile";
73 fTitle = title ? title : "Task to write one container to an ascii file";
74
75 fNameFile = filename;
76
77 fOut = new ofstream(fNameFile);
78}
79
80// --------------------------------------------------------------------------
81//
82// Specify the name of the ascii output file 'filename' and the name
83// of the container you want to write. (Normally this is the name
84// of the class (eg. MHillas) but it can also be a different name which
85// identifies the container in the parameter list.
86// Because you cannot write more than one container there is no Add-function
87// like in MWriteRootFile.
88//
89// For Example: MWriteAsciiFile("file.txt", "MHillas");
90//
91MWriteAsciiFile::MWriteAsciiFile(const char *filename, const char *contname,
92 const char *name, const char *title)
93{
94 Init(filename, name, title);
95
96 if (contname)
97 AddContainer(contname);
98}
99
100// --------------------------------------------------------------------------
101//
102// Specify a the name of the ascii output file 'filename' and a pointer to
103// the container you want to write.
104// Because you cannot write more than one container there is no Add-function
105// like in MWriteRootFile.
106//
107// For Example: MHillas hillas;
108// MWriteAsciiFile("file.txt", &hillas);
109//
110//
111MWriteAsciiFile::MWriteAsciiFile(const char *filename, MParContainer *cont,
112 const char *name, const char *title)
113{
114 Init(filename, name, title);
115
116 if (cont)
117 AddContainer(cont);
118}
119
120// --------------------------------------------------------------------------
121//
122// Destructor. Delete the output file if necessary (it is closed
123// automatically by its destructor.
124//
125MWriteAsciiFile::~MWriteAsciiFile()
126{
127 fAutoDel.SetOwner();
128 delete fOut;
129}
130
131// --------------------------------------------------------------------------
132//
133// Return open state of the file
134//
135Bool_t MWriteAsciiFile::IsFileOpen() const
136{
137 return (bool)(*fOut);
138}
139
140// --------------------------------------------------------------------------
141//
142// Add a rule to be written as a column to the ascii file.
143// For more information about rules see MDataChain.
144//
145void MWriteAsciiFile::AddRule(const char *rule)
146{
147 MDataChain *chain = new MDataChain(rule);
148 fList.Add(chain);
149}
150
151// --------------------------------------------------------------------------
152//
153// Add another container (by pointer) to be written to the ascii file.
154// The container will be output one after each other in one line.
155// If you want to write only one data member of the container
156// specify the name of the data member (eg. fAlpha) Make sure,
157// that a "GetteMethod" for this data type exists (strip the f and
158// replace it by Get)
159// If you specify a single data member you can add a scale-factor which
160// is (in case of the data member being a floating point value) multiplied
161// with the data member value. This is usefull if you are want to
162// change the scale (unit) of a data member for writing (eg.
163// writing degrees for the hillas parameters instead of the internally
164// used millimeters)
165//
166void MWriteAsciiFile::AddContainer(MParContainer *cont, const TString member, Double_t scale)
167{
168 if (member.IsNull())
169 {
170 fList.Add(cont);
171 return;
172 }
173
174 MData *data = new MDataMember(cont, member);
175
176 if (scale!=1)
177 {
178 MDataList *list = new MDataList('*');
179 MDataValue *val = new MDataValue(scale);
180
181 list->SetOwner();
182 list->AddToList(data);
183 list->AddToList(val);
184
185 data = list;
186 }
187 fList.Add(data);
188 fAutoDel.Add(data);
189}
190
191// --------------------------------------------------------------------------
192//
193// Add another container (by name) to be written to the ascii file.
194// The container will be output one after each other in one line.
195// If you want to write only one data member of the container
196// specify the name of the data member (eg. fAlpha) Make sure,
197// that a "GetteMethod" for this data type exists (strip the f and
198// replace it by Get)
199// If you specify a single data member you can add a scale-factor which
200// is (in case of the data member being a floating point value) multiplied
201// with the data member value. This is usefull if you are want to
202// change the scale (unit) of a data member for writing (eg.
203// writing degrees for the hillas parameters instead of the internally
204// used millimeters)
205//
206void MWriteAsciiFile::AddContainer(const TString cont, const TString member, Double_t scale)
207{
208 if (member.IsNull())
209 {
210 TNamed *name = new TNamed(cont, cont);
211 fList.Add(name);
212 fAutoDel.Add(name);
213 return;
214 }
215
216 MData *data = new MDataMember(Form("%s.%s", (const char*)cont, (const char*)member));
217 if (scale!=1)
218 {
219 MDataList *list = new MDataList('*');
220 MDataValue *val = new MDataValue(scale);
221
222 list->SetOwner();
223 list->AddToList(data);
224 list->AddToList(val);
225
226 data = list;
227 }
228 fList.Add(data);
229 fAutoDel.Add(data);
230}
231
232// --------------------------------------------------------------------------
233//
234// Tries to get all containers from the ParList which were given by name
235// adds them to the list of pointers to the container which should be
236// written to the ascii file.
237//
238Bool_t MWriteAsciiFile::GetContainer(MParList *plist)
239{
240 TObject *obj=NULL;
241
242 TIter Next(&fList);
243 while ((obj=Next()))
244 {
245 //
246 // MData is the highest class in the inheritance tree
247 //
248 if (obj->InheritsFrom(MData::Class()))
249 {
250 if (!((MData*)obj)->PreProcess(plist))
251 return kFALSE;
252 continue;
253 }
254
255 //
256 // MParContainer is the next class in the inheritance tree
257 //
258 if (obj->InheritsFrom(MParContainer::Class()))
259 continue;
260
261 //
262 // It is neither a MData nor a MParContainer, it must be a TNamed
263 //
264 TObject *o = plist->FindObject(obj->GetName());
265 if (!o)
266 return kFALSE;
267
268 fList[fList.IndexOf(obj)] = o;
269 }
270 return kTRUE;
271}
272
273// --------------------------------------------------------------------------
274//
275// Check if the containers are ready for writing. If so write them.
276// The containers are written in one line, one after each other.
277// If not all containers are written (because of the IsReadyToSave-flag)
278// a warning message is print.
279//
280void MWriteAsciiFile::CheckAndWrite() const
281{
282 Bool_t written = kFALSE;
283
284 MParContainer *obj = NULL;
285
286 Int_t num = fList.GetEntries();
287
288 TIter Next(&fList);
289 while ((obj=(MParContainer*)Next()))
290 {
291 if (!obj->IsReadyToSave())
292 continue;
293
294 if (!obj->AsciiWrite(*fOut))
295 continue;
296
297 written = kTRUE;
298
299 num--;
300 }
301
302 if (!written)
303 return;
304
305 *fOut << endl;
306
307 if (num!=0)
308 *fLog << warn << "Warning - given number of objects doesn't fit number of written objects." << endl;
309}
310
Note: See TracBrowser for help on using the repository browser.