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

Last change on this file since 3167 was 3167, checked in by ansari, 19 years ago

Passage a la version ll (LONGLONG) des routines fits , cmv+Reza 02/02/2007

File size: 12.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
[3069]190 sa_size_t segsz = is.GetNbRows() / 64; // Taille de segment par defaut
[2820]191 if (segsz > 2048) segsz = 2048;
192 string key = "SEGMSIZE";
[2846]193 bool knex = false;
194 string ssegsz = is.KeyValue(key, knex);
[3069]195 bool fgsss = false;
196 if (!knex && (ssegsz.length() > 0)) { segsz = atoi(ssegsz.c_str()); fgsss = true; }
[2820]197 if (segsz < 16) segsz = 16;
198
[2889]199 // Nb de lignes et de colonnes
200 vector<string> colnames;
201 vector<int> coltypes;
[3167]202 vector<LONGLONG> repcnt, width;
203 vector<sa_size_t> colpos;
[2889]204 is.GetColInfo(colnames, coltypes, repcnt, width);
[3167]205 int_8 nbrows = is.GetNbRows();
[2889]206
[2820]207 if (dobj == NULL) { // On cree la table si besoin
[3069]208 /*
209 Reza, Sep06 : On ne cree pas automatiquement un SwFitsDataTable -
210 En effet, on ne peut garantir que l'objet FitsInOutFile is reste
211 valide pendant toute la duree de vie de l'objet SwFitsDataTable
212
[2889]213 string key = "SOPCLSNM";
214 string clsnm = is.KeyValue(key);
[3069]215 if ( (clsnm == "SOPHYA::SwFitsDataTable") || (nbrows*colnames.size() < 10000000) )
[2889]216 dobj = new DataTable(segsz);
[3069]217 else {
218 dobj = new SwFitsDataTable(segsz);
219 // dobj = new SwFitsDataTable(is, segsz, false);
220 // Reza, Sep2006: Ce constructeur de SwFitsDataTable lit l'entete
221 // et initialise donc l'objet SwFitsDataTable -> return
222 // return;
223 }
224 */
225 dobj = new DataTable(segsz);
[2820]226 }
227 else {
228 dobj->Clear(); // On efface la table sinon
[3069]229 if (fgsss) dobj->mSegSz = segsz;
[2820]230 }
231
[2889]232 // Type reel de table
[2820]233 DataTable* dt = dynamic_cast< DataTable *> (dobj);
[2889]234 SwFitsDataTable* swfdt = dynamic_cast< SwFitsDataTable *> (dobj);
235
236 vector<int_8> swpos;
[3069]237 segsz = dobj->mSegSz;
238 int_8 swp = 1;
239 while (swp < nbrows) {
240 swpos.push_back(swp); swp += segsz;
241 }
[2889]242 // Initialize the fits swap stream for SwFitsDataTable if necessary
243 if (swfdt) {
[3069]244 if ( swfdt->FitsSwapFile().FitsPtr() != is.FitsPtr() ) {
245 // swfdt->FitsSwapFile().Close();
246 // swfdt->FitsSwapFile().Open(is.FileName().c_str(), FitsInOutFile::Fits_RO);
247 // swfdt->FitsSwapFile().MoveAbsToHDU(is.CurrentHDU());
[2889]248 swfdt->FitsSwapFile().ShareFitsPtr(is);
249 }
250 }
251
[2820]252 // --ATTENTION-- repcnt (contenu=vecteur) pas pris en compte pour le moment
253 for(sa_size_t k=0; k<colnames.size(); k++) {
[2963]254 string ocolnm = colnames[k];
255 if (dobj->CheckCorrectColName(colnames[k]) )
256 cout << "FitsHandler<BaseDataTable>::Read()/Warning Column name changed for col["
257 << k << "] " << ocolnm << " -> " << colnames[k] << endl;
258
[2820]259 switch ( coltypes[k] ) {
260 case TBYTE :
261 case TSHORT :
262 case TUSHORT :
263 case TINT :
[2889]264 if (swfdt)
265 swfdt->AddColRd(BaseDataTable::IntegerField, colnames[k], k+1, &swpos);
266 else dobj->AddIntegerColumn(colnames[k]);
[2820]267 colpos.push_back(k+1);
268 break;
269 case TUINT:
270 case TLONG :
271 case TULONG :
272#ifdef TLONGLONG
273 case TLONGLONG :
[2889]274#endif
275 if (swfdt)
276 swfdt->AddColRd(BaseDataTable::LongField, colnames[k], k+1, &swpos);
277 else dobj->AddLongColumn(colnames[k]);
[2820]278 colpos.push_back(k+1);
279 break;
280 case TFLOAT :
[2889]281 if (swfdt)
282 swfdt->AddColRd(BaseDataTable::FloatField, colnames[k], k+1, &swpos);
283 else dobj->AddFloatColumn(colnames[k]);
[2820]284 colpos.push_back(k+1);
285 break;
286 case TDOUBLE :
[2889]287 if (swfdt)
288 swfdt->AddColRd(BaseDataTable::DoubleField, colnames[k], k+1, &swpos);
289 else dobj->AddDoubleColumn(colnames[k]);
[2820]290 colpos.push_back(k+1);
291 break;
[2846]292 case TCOMPLEX :
[2889]293 if (swfdt)
294 swfdt->AddColRd(BaseDataTable::ComplexField, colnames[k], k+1, &swpos);
295 else dobj->AddComplexColumn(colnames[k]);
[2846]296 colpos.push_back(k+1);
297 break;
298 case TDBLCOMPLEX :
[2889]299 if (swfdt)
300 swfdt->AddColRd(BaseDataTable::DoubleComplexField, colnames[k], k+1, &swpos);
301 else dobj->AddDoubleComplexColumn(colnames[k]);
[2846]302 colpos.push_back(k+1);
303 break;
304 case TSTRING :
[2889]305 if (swfdt)
306 swfdt->AddColRd(BaseDataTable::StringField, colnames[k], k+1, &swpos);
307 else dobj->AddStringColumn(colnames[k]);
[2846]308 colpos.push_back(k+1);
309 break;
[2820]310 default:
311 cout << "FitsHandler<BaseDataTable>::Read() NOT handled field type "
312 << coltypes[k] << endl;
313 break;
314 }
315 }
316
317 // ------- Mise a jour des champs Nb d'entrees, nb segments ...
318 dobj->mNEnt = is.GetNbRows();
[2889]319 // Lecture DVList (=entete FITS)
320 is.GetHeaderRecords(dobj->Info());
321
322 // On ne doit pas lire les donnees de la table pour un SwFitsDataTable
[3069]323 if (swfdt) {
324 swfdt->mNSeg = swpos.size();
325 return;
326 }
[2889]327
[2820]328 while ((dobj->SegmentSize()*dobj->NbSegments()) < dobj->NEntry())
329 dobj->Extend();
[2846]330 //DBG cout << " DBG2 -- dobj->mNSeg = " << dobj->NbSegments() << " SegSize="
331 //DBG << dobj->SegmentSize() << " NEntry=" << dobj->NEntry() << endl;
[2820]332
333 // Lecture des donnees des colonnes
334 for(sa_size_t l=0; l<dobj->NEntry(); l+=dobj->SegmentSize()) {
335 sa_size_t icol = 0;
336 sa_size_t sz = dobj->SegmentSize();
337 sa_size_t iseg = l/sz;
338 if ((l+sz) > dobj->NEntry()) sz = dobj->NEntry()-l;
339 for(sa_size_t k=0; k<dobj->NVar(); k++) {
340 sa_size_t sk = dobj->mNames[k].ser;
341 icol = colpos[k];
342 // cout << " DBG-3 , k=" << k << " icol=" << icol << endl;
343 switch ( dobj->GetColumType(k) ) {
344 case BaseDataTable::IntegerField :
345 FitsBlockRW<int_4>::ReadColumnData(is, icol, l+1, 1,
[2889]346 dobj->mIColsP[sk]->GetSegment(iseg), sz);
[2820]347 break;
348 case BaseDataTable::LongField :
349 FitsBlockRW<int_8>::ReadColumnData(is, icol, l+1, 1,
[2889]350 dobj->mLColsP[sk]->GetSegment(iseg), sz);
[2820]351 break;
352 case BaseDataTable::FloatField :
353 FitsBlockRW<r_4>::ReadColumnData(is, icol, l+1, 1,
[2889]354 dobj->mFColsP[sk]->GetSegment(iseg), sz);
[2820]355 break;
356 case BaseDataTable::DoubleField :
[2846]357 case BaseDataTable::DateTimeField :
[2820]358 FitsBlockRW<r_8>::ReadColumnData(is, icol, l+1, 1,
[2889]359 dobj->mDColsP[sk]->GetSegment(iseg), sz);
[2820]360 break;
[2846]361 case BaseDataTable::ComplexField :
362 FitsBlockRW< complex<r_4> >::ReadColumnData(is, icol, l+1, 1,
[2889]363 dobj->mYColsP[sk]->GetSegment(iseg), sz);
[2846]364 break;
365 case BaseDataTable::DoubleComplexField :
366 FitsBlockRW< complex<r_8> >::ReadColumnData(is, icol, l+1, 1,
[2889]367 dobj->mZColsP[sk]->GetSegment(iseg), sz);
[2846]368 break;
369 case BaseDataTable::StringField :
370 FitsBlockRW<std::string>::ReadColumnData(is, icol, l+1, 1,
[2889]371 dobj->mSColsP[sk]->GetSegment(iseg), sz);
[2846]372 break;
[2820]373 default:
374 break;
375 }
376 }
377 }
378
379}
380
381
382
383
Note: See TracBrowser for help on using the repository browser.