source: Sophya/trunk/SophyaExt/FitsIOServer/fitshdtable.cc

Last change on this file was 3237, checked in by ansari, 18 years ago

suppression include sopnamsp.h et mis la declaration namespace SOPHYA ds les fichiers .cc quand DECL_TEMP_SPEC ds le fichier , cmv+reza 27/04/2007

File size: 12.4 KB
Line 
1#include "machdefs.h"
2
3#include <stdio.h>
4#include <string.h>
5#include <iostream>
6#include <typeinfo>
7
8#include "datatable.h"
9#include "fitsblkrw.h"
10#include "fitshandler.h"
11#include "swfitsdtable.h"
12
13namespace SOPHYA {
14
15DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
16int FitsHandler<BaseDataTable>::CheckReadability(FitsInOutFile& is)
17{
18 if (is.CurrentHDUType() == IMAGE_HDU ) return 0;
19 string key = "SOPCLSNM";
20 string clsnm = is.KeyValue(key);
21 if ( (clsnm == "SOPHYA::DataTable") || (clsnm == "SOPHYA::SwFitsDataTable") )
22 return 2;
23 else return 1;
24}
25
26DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
27void FitsHandler<BaseDataTable>::Write(FitsInOutFile& os)
28{
29
30 if (dobj == NULL)
31 throw NullPtrError("FitsHandler<DataTable>::Write() NULL dobj pointer ");
32
33 DataTable* dt = dynamic_cast< DataTable *> (dobj);
34 SwFitsDataTable* swfdt = dynamic_cast< SwFitsDataTable *> (dobj);
35
36 int tbltyp = os.GetDef_TableType();
37 if ( swfdt && (tbltyp == ASCII_TBL) )
38 throw FitsIOException("FitsHandler<DataTable>::Write() ASCII_TBL not supported for SwFitsDataTable");
39
40 // On ne reecrit pas la definition d'une SwFitsDataTable dans son fichier de swap
41 if (swfdt && (swfdt->mSwF.FitsPtr()==os.FitsPtr()) && swfdt->NRows() ) return;
42
43 string strcoltag;
44 long strwidth = os.GetDef_StrColWidth();
45 if (strwidth < 1) strwidth = 16;
46 char buff[32];
47 if (tbltyp == ASCII_TBL)
48 sprintf(buff, "A%ld",strwidth);
49 else
50 sprintf(buff, "%ldA",strwidth);
51 strcoltag = buff;
52
53 vector<string> colnames, tform, tunit;
54 for(sa_size_t k=0; k<dobj->NVar(); k++) {
55 bool fgoknm = true;
56 bool fgoktun = true;
57 switch ( dobj->GetColumType(k) ) {
58 case BaseDataTable::IntegerField :
59 if (tbltyp == ASCII_TBL) tform.push_back("I9");
60 else tform.push_back("J");
61 break;
62 case BaseDataTable::LongField :
63 if (tbltyp == ASCII_TBL) tform.push_back("I12");
64 else tform.push_back("K");
65 break;
66 case BaseDataTable::FloatField :
67 if (tbltyp == ASCII_TBL) tform.push_back("E12.5");
68 else tform.push_back("E");
69 break;
70 case BaseDataTable::DoubleField :
71 case BaseDataTable::DateTimeField :
72 if (tbltyp == ASCII_TBL) tform.push_back("D15.8");
73 else tform.push_back("D");
74 if (dobj->GetColumType(k) == BaseDataTable::DateTimeField ) {
75 tunit.push_back("Days (DateTimeField)");
76 fgoktun = false;
77 }
78 break;
79 case BaseDataTable::ComplexField :
80 if (tbltyp == ASCII_TBL) {
81 cout << "FitsHandler<BaseDataTable>::Write()/Warning ComplexField not supported for ASCII_TBL "
82 << endl;
83 fgoknm = false;
84 }
85 else tform.push_back("C");
86 break;
87 case BaseDataTable::DoubleComplexField :
88 if (tbltyp == ASCII_TBL) {
89 cout << "FitsHandler<BaseDataTable>::Write()/Warning DoubleComplexField not supported for ASCII_TBL "
90 << endl;
91 fgoknm = false;
92 }
93 else tform.push_back("M");
94 break;
95 case BaseDataTable::StringField :
96 tform.push_back(strcoltag);
97 break;
98 default:
99 throw IOExc("FitsHandler<BaseDataTable>::Write() unknown column type ");
100 break;
101 }
102 if (fgoknm) {
103 colnames.push_back(dobj->GetColumName(k));
104 if (fgoktun) tunit.push_back("");
105 }
106 }
107
108 // On cree la table
109 string extname = os.NextExtensionName();
110 os.CreateTable(os.GetDef_TableType(), extname, colnames, tform, tunit);
111
112 // On n'ecrit pas les donnees d'une table SwFitsDataTable ds son fichier de swap
113 if (swfdt && (swfdt->mSwF.FitsPtr()==os.FitsPtr()) ) return;
114
115 // Ecriture des donnees des colonnes
116 for(sa_size_t l=0; l<dobj->NEntry(); l+=dobj->SegmentSize()) {
117 sa_size_t icol = 0;
118 sa_size_t sz = dobj->SegmentSize();
119 sa_size_t iseg = l/sz;
120 if ((l+sz) > dobj->NEntry()) sz = dobj->NEntry()-l;
121 for(sa_size_t k=0; k<dobj->NVar(); k++) {
122 sa_size_t sk = dobj->mNames[k].ser;
123 //DBG cout << "DBG-A k= " << k << " nom=" << dobj->mNames[k].nom << " ser=" << sk
124 //DBG << " type=" << dobj->GetColumType(k) << endl;
125 switch ( dobj->GetColumType(k) ) {
126 case BaseDataTable::IntegerField :
127 icol++;
128 FitsBlockRW<int_4>::WriteColumnData(os, icol, l+1, 1,
129 dobj->mIColsP[sk]->GetCstSegment(iseg), sz);
130 break;
131 case BaseDataTable::LongField :
132 icol++;
133 FitsBlockRW<int_8>::WriteColumnData(os, icol, l+1, 1,
134 dobj->mLColsP[sk]->GetCstSegment(iseg), sz);
135 break;
136 case BaseDataTable::FloatField :
137 icol++;
138 FitsBlockRW<r_4>::WriteColumnData(os, icol, l+1, 1,
139 dobj->mFColsP[sk]->GetCstSegment(iseg), sz);
140 break;
141 case BaseDataTable::DoubleField :
142 case BaseDataTable::DateTimeField :
143 icol++;
144 FitsBlockRW<r_8>::WriteColumnData(os, icol, l+1, 1,
145 dobj->mDColsP[sk]->GetCstSegment(iseg), sz);
146 break;
147 case BaseDataTable::ComplexField :
148 if (tbltyp == BINARY_TBL) {
149 icol++;
150 FitsBlockRW< complex<r_4> >::WriteColumnData(os, icol, l+1, 1,
151 dobj->mYColsP[sk]->GetCstSegment(iseg), sz);
152 }
153 break;
154 case BaseDataTable::DoubleComplexField :
155 if (tbltyp == BINARY_TBL) {
156 icol++;
157 FitsBlockRW< complex<r_8> >::WriteColumnData(os, icol, l+1, 1,
158 dobj->mZColsP[sk]->GetCstSegment(iseg), sz);
159 }
160 break;
161 case BaseDataTable::StringField :
162 icol++;
163 FitsBlockRW<std::string>::WriteColumnData(os, icol, l+1, 1,
164 dobj->mSColsP[sk]->GetCstSegment(iseg), sz);
165 break;
166 default:
167 break;
168 }
169 }
170 }
171
172 // Ecriture de SegmentSize et autre elements de DVList
173 os.WriteHeaderRecords(dobj->Info());
174 MuTyV mtv = dobj->SegmentSize();
175 os.WriteKey("SEGMSIZE",mtv," SOPHYA::DataTable SegmentSize");
176 mtv = "SOPHYA::DataTable";
177 os.WriteKey("SOPCLSNM",mtv," Object class name ");
178}
179
180
181
182DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
183void FitsHandler<BaseDataTable>::Read(FitsInOutFile& is)
184{
185
186 int hdutyp = is.CurrentHDUType();
187 if ( (hdutyp != BINARY_TBL ) && (hdutyp != ASCII_TBL) )
188 throw FitsIOException("FitsHandler<DataTable>::Read() Not a binary or ascii table HDU");
189
190 // Determination de la taille de segment
191 sa_size_t segsz = is.GetNbRows() / 64; // Taille de segment par defaut
192 if (segsz > 2048) segsz = 2048;
193 string key = "SEGMSIZE";
194 bool knex = false;
195 string ssegsz = is.KeyValue(key, knex);
196 bool fgsss = false;
197 if (!knex && (ssegsz.length() > 0)) { segsz = atoi(ssegsz.c_str()); fgsss = true; }
198 if (segsz < 16) segsz = 16;
199
200 // Nb de lignes et de colonnes
201 vector<string> colnames;
202 vector<int> coltypes;
203 vector<LONGLONG> repcnt, width;
204 vector<sa_size_t> colpos;
205 is.GetColInfo(colnames, coltypes, repcnt, width);
206 int_8 nbrows = is.GetNbRows();
207
208 if (dobj == NULL) { // On cree la table si besoin
209 /*
210 Reza, Sep06 : On ne cree pas automatiquement un SwFitsDataTable -
211 En effet, on ne peut garantir que l'objet FitsInOutFile is reste
212 valide pendant toute la duree de vie de l'objet SwFitsDataTable
213
214 string key = "SOPCLSNM";
215 string clsnm = is.KeyValue(key);
216 if ( (clsnm == "SOPHYA::SwFitsDataTable") || (nbrows*colnames.size() < 10000000) )
217 dobj = new DataTable(segsz);
218 else {
219 dobj = new SwFitsDataTable(segsz);
220 // dobj = new SwFitsDataTable(is, segsz, false);
221 // Reza, Sep2006: Ce constructeur de SwFitsDataTable lit l'entete
222 // et initialise donc l'objet SwFitsDataTable -> return
223 // return;
224 }
225 */
226 dobj = new DataTable(segsz);
227 }
228 else {
229 dobj->Clear(); // On efface la table sinon
230 if (fgsss) dobj->mSegSz = segsz;
231 }
232
233 // Type reel de table
234 DataTable* dt = dynamic_cast< DataTable *> (dobj);
235 SwFitsDataTable* swfdt = dynamic_cast< SwFitsDataTable *> (dobj);
236
237 vector<int_8> swpos;
238 segsz = dobj->mSegSz;
239 int_8 swp = 1;
240 while (swp < nbrows) {
241 swpos.push_back(swp); swp += segsz;
242 }
243 // Initialize the fits swap stream for SwFitsDataTable if necessary
244 if (swfdt) {
245 if ( swfdt->FitsSwapFile().FitsPtr() != is.FitsPtr() ) {
246 // swfdt->FitsSwapFile().Close();
247 // swfdt->FitsSwapFile().Open(is.FileName().c_str(), FitsInOutFile::Fits_RO);
248 // swfdt->FitsSwapFile().MoveAbsToHDU(is.CurrentHDU());
249 swfdt->FitsSwapFile().ShareFitsPtr(is);
250 }
251 }
252
253 // --ATTENTION-- repcnt (contenu=vecteur) pas pris en compte pour le moment
254 for(sa_size_t k=0; k<colnames.size(); k++) {
255 string ocolnm = colnames[k];
256 if (dobj->CheckCorrectColName(colnames[k]) )
257 cout << "FitsHandler<BaseDataTable>::Read()/Warning Column name changed for col["
258 << k << "] " << ocolnm << " -> " << colnames[k] << endl;
259
260 switch ( coltypes[k] ) {
261 case TBYTE :
262 case TSHORT :
263 case TUSHORT :
264 case TINT :
265 if (swfdt)
266 swfdt->AddColRd(BaseDataTable::IntegerField, colnames[k], k+1, &swpos);
267 else dobj->AddIntegerColumn(colnames[k]);
268 colpos.push_back(k+1);
269 break;
270 case TUINT:
271 case TLONG :
272 case TULONG :
273#ifdef TLONGLONG
274 case TLONGLONG :
275#endif
276 if (swfdt)
277 swfdt->AddColRd(BaseDataTable::LongField, colnames[k], k+1, &swpos);
278 else dobj->AddLongColumn(colnames[k]);
279 colpos.push_back(k+1);
280 break;
281 case TFLOAT :
282 if (swfdt)
283 swfdt->AddColRd(BaseDataTable::FloatField, colnames[k], k+1, &swpos);
284 else dobj->AddFloatColumn(colnames[k]);
285 colpos.push_back(k+1);
286 break;
287 case TDOUBLE :
288 if (swfdt)
289 swfdt->AddColRd(BaseDataTable::DoubleField, colnames[k], k+1, &swpos);
290 else dobj->AddDoubleColumn(colnames[k]);
291 colpos.push_back(k+1);
292 break;
293 case TCOMPLEX :
294 if (swfdt)
295 swfdt->AddColRd(BaseDataTable::ComplexField, colnames[k], k+1, &swpos);
296 else dobj->AddComplexColumn(colnames[k]);
297 colpos.push_back(k+1);
298 break;
299 case TDBLCOMPLEX :
300 if (swfdt)
301 swfdt->AddColRd(BaseDataTable::DoubleComplexField, colnames[k], k+1, &swpos);
302 else dobj->AddDoubleComplexColumn(colnames[k]);
303 colpos.push_back(k+1);
304 break;
305 case TSTRING :
306 if (swfdt)
307 swfdt->AddColRd(BaseDataTable::StringField, colnames[k], k+1, &swpos);
308 else dobj->AddStringColumn(colnames[k]);
309 colpos.push_back(k+1);
310 break;
311 default:
312 cout << "FitsHandler<BaseDataTable>::Read() NOT handled field type "
313 << coltypes[k] << endl;
314 break;
315 }
316 }
317
318 // ------- Mise a jour des champs Nb d'entrees, nb segments ...
319 dobj->mNEnt = is.GetNbRows();
320 // Lecture DVList (=entete FITS)
321 is.GetHeaderRecords(dobj->Info());
322
323 // On ne doit pas lire les donnees de la table pour un SwFitsDataTable
324 if (swfdt) {
325 swfdt->mNSeg = swpos.size();
326 return;
327 }
328
329 while ((dobj->SegmentSize()*dobj->NbSegments()) < dobj->NEntry())
330 dobj->Extend();
331 //DBG cout << " DBG2 -- dobj->mNSeg = " << dobj->NbSegments() << " SegSize="
332 //DBG << dobj->SegmentSize() << " NEntry=" << dobj->NEntry() << endl;
333
334 // Lecture des donnees des colonnes
335 for(sa_size_t l=0; l<dobj->NEntry(); l+=dobj->SegmentSize()) {
336 sa_size_t icol = 0;
337 sa_size_t sz = dobj->SegmentSize();
338 sa_size_t iseg = l/sz;
339 if ((l+sz) > dobj->NEntry()) sz = dobj->NEntry()-l;
340 for(sa_size_t k=0; k<dobj->NVar(); k++) {
341 sa_size_t sk = dobj->mNames[k].ser;
342 icol = colpos[k];
343 // cout << " DBG-3 , k=" << k << " icol=" << icol << endl;
344 switch ( dobj->GetColumType(k) ) {
345 case BaseDataTable::IntegerField :
346 FitsBlockRW<int_4>::ReadColumnData(is, icol, l+1, 1,
347 dobj->mIColsP[sk]->GetSegment(iseg), sz);
348 break;
349 case BaseDataTable::LongField :
350 FitsBlockRW<int_8>::ReadColumnData(is, icol, l+1, 1,
351 dobj->mLColsP[sk]->GetSegment(iseg), sz);
352 break;
353 case BaseDataTable::FloatField :
354 FitsBlockRW<r_4>::ReadColumnData(is, icol, l+1, 1,
355 dobj->mFColsP[sk]->GetSegment(iseg), sz);
356 break;
357 case BaseDataTable::DoubleField :
358 case BaseDataTable::DateTimeField :
359 FitsBlockRW<r_8>::ReadColumnData(is, icol, l+1, 1,
360 dobj->mDColsP[sk]->GetSegment(iseg), sz);
361 break;
362 case BaseDataTable::ComplexField :
363 FitsBlockRW< complex<r_4> >::ReadColumnData(is, icol, l+1, 1,
364 dobj->mYColsP[sk]->GetSegment(iseg), sz);
365 break;
366 case BaseDataTable::DoubleComplexField :
367 FitsBlockRW< complex<r_8> >::ReadColumnData(is, icol, l+1, 1,
368 dobj->mZColsP[sk]->GetSegment(iseg), sz);
369 break;
370 case BaseDataTable::StringField :
371 FitsBlockRW<std::string>::ReadColumnData(is, icol, l+1, 1,
372 dobj->mSColsP[sk]->GetSegment(iseg), sz);
373 break;
374 default:
375 break;
376 }
377 }
378 }
379
380}
381
382
383} // FIN namespace SOPHYA
384
385
Note: See TracBrowser for help on using the repository browser.