source: trunk/MagicSoft/Mars/mbase/MLut.cc@ 9301

Last change on this file since 9301 was 9257, checked in by tbretz, 16 years ago
*** empty log message ***
File size: 7.3 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of CheObs, the Modular 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 appears 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, 1/2009 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: CheObs Software Development, 2000-2009
21!
22!
23\* ======================================================================== */
24
25//////////////////////////////////////////////////////////////////////////////
26//
27// MLut
28//
29// This is a simple and easy-to-use implementation of a look-up table with
30// rows of different lengths.
31//
32//////////////////////////////////////////////////////////////////////////////
33#include "MLut.h"
34
35#include <errno.h>
36#include <fstream>
37
38#include <stdlib.h> // atoi (Ubuntu 8.10)
39
40#include "MLog.h"
41#include "MLogManip.h"
42
43#include "MArrayI.h"
44
45ClassImp(MLut);
46
47using namespace std;
48
49// --------------------------------------------------------------------------
50//
51// Get the i-th entry in the routing table. Note, that i is not
52// range checked, but for any valid i a valid MArrayI is returned.
53//
54const MArrayI &MLut::GetRow(UInt_t i) const
55{
56 return *static_cast<MArrayI*>(UncheckedAt(i));
57}
58
59// --------------------------------------------------------------------------
60//
61// Return the inverse lut of the current lut. The user is responsible
62// of deleting the allocated and returned MLut.
63//
64// For an example see Inverse()
65//
66MLut *MLut::GetInverse(Bool_t uniq) const
67{
68 MLut *lut = new MLut;
69 lut->SetInverse(*this, uniq);
70 return lut;
71}
72
73// --------------------------------------------------------------------------
74//
75// Set this to the inverse lut of the given argument.
76//
77// For an example see Inverse()
78//
79void MLut::SetInverse(const MLut &lut, Bool_t uniq)
80{
81 if (&lut==this)
82 {
83 Invert(uniq);
84 return;
85 }
86
87 // Delete the current lut
88 Delete();
89
90 // Add as many MArrayI as needed
91 for (Int_t i=0; i<=lut.fMaxIndex; i++)
92 Add(new MArrayI);
93
94 // Get the number of rows in the given lut
95 const UInt_t num = lut.GetEntriesFast();
96
97 // Loop over all rows
98 for (UInt_t y=0; y<num; y++)
99 {
100 // Get the y-th row
101 const MArrayI &arr = lut.GetRow(y);
102
103 // Loop over all entries in this row
104 for (UInt_t x=0; x<arr.GetSize(); x++)
105 {
106 // If the entry is valid convert it to the right position in
107 // the new lut
108 if (arr[x]<0)
109 continue;
110
111 MArrayI &row = *static_cast<MArrayI*>(UncheckedAt(arr[x]));
112 if (uniq)
113 row.AddUniq(y);
114 else
115 row.Add(y);
116 }
117 }
118
119 // Reset the statistics
120 fMaxEntries = 0;
121 fMinEntries = 0;
122
123 // Loop over all new MArrayI
124 for (Int_t i=0; i<=lut.fMaxIndex; i++)
125 {
126 // Get i-th row
127 MArrayI &row = *static_cast<MArrayI*>(UncheckedAt(i));
128
129 // Sort the i-th row ascending
130 row.ReSort();
131
132 // Get the number of entries in the row
133 UInt_t n = row.GetSize();
134
135 // For convinience (to avoid empty lines in a file)
136 // add -1 to empty rows
137 if (n==0)
138 {
139 row.Add(-1);
140 n=1;
141 }
142
143 // Get the new min and max
144 if (n<fMinEntries || fMinEntries==0)
145 fMinEntries = n;
146 if (n>fMaxEntries)
147 fMaxEntries = n;
148 }
149
150 // set the new highest index in the table
151 fMaxIndex = num-1;
152}
153
154// --------------------------------------------------------------------------
155//
156// Inverts the current lut, for example
157//
158// 0: --
159// 0: 1 2 ---\ 1: 0
160// 1: 2 3 ---/ 2: 0 1
161// 3: 1
162//
163void MLut::Invert(Bool_t uniq)
164{
165 MLut *lut = GetInverse(uniq);
166
167 Delete();
168
169 for (Int_t i=0; i<=fMaxIndex; i++)
170 Add(lut->Remove(lut->UncheckedAt(i)));
171
172 fMaxEntries = lut->fMaxEntries;
173 fMinEntries = lut->fMinEntries;
174 fMaxIndex = lut->fMaxIndex;
175
176 delete lut;
177}
178
179// --------------------------------------------------------------------------
180//
181// Read a lut from a stream.
182//
183// The row in the lut is just identical to the line in the stream.
184// The entries in one line must be seperated by a whitespace.
185// The lines can have a different number of entries.
186//
187Int_t MLut::ReadStream(istream &fin)
188{
189 Delete();
190
191 fMaxIndex = -1;
192 fMaxEntries = 0;
193 fMinEntries = 0;
194
195 while (1)
196 {
197 TString line;
198 line.ReadLine(fin);
199 if (!fin)
200 break;
201
202 // Split line by whitespaces
203 TObjArray *tokens = line.Tokenize(' ');
204
205 // Get number of entries in this row
206 const UInt_t n = tokens->GetEntries();
207
208 // Calculate minimum and maximum numbers of entries per row
209 if (n<fMinEntries || fMinEntries==0)
210 fMinEntries = n;
211 if (n>fMaxEntries)
212 fMaxEntries = n;
213
214 // create new entry for this row and add it to the array
215 MArrayI &idx = *new MArrayI(n);
216 Add(&idx);
217
218 // loop over all entries in this row
219 for (UInt_t i=0; i<n; i++)
220 {
221 // Convert strings to numbers
222 idx[i] = atoi((*tokens)[i]->GetName());
223
224 // Calculate maximum existing index
225 if (idx[i]>fMaxIndex)
226 fMaxIndex = idx[i];
227 }
228
229 // delete allocated TObjArray
230 delete tokens;
231 }
232
233 return GetEntries();
234}
235
236// --------------------------------------------------------------------------
237//
238// Write a lut to a stream.
239//
240Int_t MLut::WriteStream(ostream &out)
241{
242 const Int_t n = GetEntriesFast();
243 for (int y=0; y<n; y++)
244 {
245 const MArrayI &arr = GetRow(y);
246
247 if (arr.GetSize()==0)
248 out << -1 << endl;
249
250 for (UInt_t x=0; x<arr.GetSize(); x++)
251 out << arr[x] << " ";
252 out << endl;
253 }
254
255 return n;
256}
257
258// --------------------------------------------------------------------------
259//
260// Read a lut from a file (see also ReadStream)
261//
262Int_t MLut::ReadFile(const char *fname)
263{
264 TString expname(fname);
265 gSystem->ExpandPathName(expname);
266
267 ifstream fin(expname);
268 if (!fin)
269 {
270 gLog << err << "Cannot open file " << expname << ": ";
271 gLog << (errno!=0?strerror(errno):"Insufficient memory for decompression") << endl;
272 return -1;
273 }
274 return ReadStream(fin);
275}
276
277// --------------------------------------------------------------------------
278//
279// Write a lut to a file
280//
281Int_t MLut::WriteFile(const char *fname)
282{
283 TString expname(fname);
284 gSystem->ExpandPathName(expname);
285
286 ofstream fout(expname);
287 if (!fout)
288 {
289 gLog << err << "Cannot open file " << expname << ": ";
290 gLog << (errno!=0?strerror(errno):"Insufficient memory for decompression") << endl;
291 return -1;
292 }
293
294 return WriteStream(fout);
295}
Note: See TracBrowser for help on using the repository browser.