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

Last change on this file since 3412 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.