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

Last change on this file since 2928 was 2889, checked in by ansari, 20 years ago

Mise au point de la classe SwFitsDataTable - Reza 9/01/2006

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