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
RevLine 
[2820]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"
[2889]11#include "swfitsdtable.h"
[2820]12
[3237]13namespace SOPHYA {
14
[2820]15DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
[2864]16int FitsHandler<BaseDataTable>::CheckReadability(FitsInOutFile& is)
17{
18 if (is.CurrentHDUType() == IMAGE_HDU ) return 0;
19 string key = "SOPCLSNM";
[2889]20 string clsnm = is.KeyValue(key);
21 if ( (clsnm == "SOPHYA::DataTable") || (clsnm == "SOPHYA::SwFitsDataTable") )
22 return 2;
[2864]23 else return 1;
24}
25
26DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
[2820]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);
[2889]34 SwFitsDataTable* swfdt = dynamic_cast< SwFitsDataTable *> (dobj);
35
[2820]36 int tbltyp = os.GetDef_TableType();
[2889]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
[2846]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
[2820]53 vector<string> colnames, tform, tunit;
54 for(sa_size_t k=0; k<dobj->NVar(); k++) {
[2846]55 bool fgoknm = true;
56 bool fgoktun = true;
[2820]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 :
[2846]71 case BaseDataTable::DateTimeField :
[2820]72 if (tbltyp == ASCII_TBL) tform.push_back("D15.8");
73 else tform.push_back("D");
[2846]74 if (dobj->GetColumType(k) == BaseDataTable::DateTimeField ) {
75 tunit.push_back("Days (DateTimeField)");
76 fgoktun = false;
77 }
[2820]78 break;
[2846]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;
[2820]95 case BaseDataTable::StringField :
[2846]96 tform.push_back(strcoltag);
[2820]97 break;
98 default:
99 throw IOExc("FitsHandler<BaseDataTable>::Write() unknown column type ");
100 break;
101 }
[2846]102 if (fgoknm) {
103 colnames.push_back(dobj->GetColumName(k));
104 if (fgoktun) tunit.push_back("");
105 }
[2820]106 }
107
108 // On cree la table
[2846]109 string extname = os.NextExtensionName();
[2820]110 os.CreateTable(os.GetDef_TableType(), extname, colnames, tform, tunit);
111
[2889]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
[2820]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;
[2846]123 //DBG cout << "DBG-A k= " << k << " nom=" << dobj->mNames[k].nom << " ser=" << sk
124 //DBG << " type=" << dobj->GetColumType(k) << endl;
[2820]125 switch ( dobj->GetColumType(k) ) {
126 case BaseDataTable::IntegerField :
127 icol++;
128 FitsBlockRW<int_4>::WriteColumnData(os, icol, l+1, 1,
[2889]129 dobj->mIColsP[sk]->GetCstSegment(iseg), sz);
[2820]130 break;
131 case BaseDataTable::LongField :
132 icol++;
133 FitsBlockRW<int_8>::WriteColumnData(os, icol, l+1, 1,
[2889]134 dobj->mLColsP[sk]->GetCstSegment(iseg), sz);
[2820]135 break;
136 case BaseDataTable::FloatField :
137 icol++;
138 FitsBlockRW<r_4>::WriteColumnData(os, icol, l+1, 1,
[2889]139 dobj->mFColsP[sk]->GetCstSegment(iseg), sz);
[2820]140 break;
141 case BaseDataTable::DoubleField :
[2846]142 case BaseDataTable::DateTimeField :
[2820]143 icol++;
144 FitsBlockRW<r_8>::WriteColumnData(os, icol, l+1, 1,
[2889]145 dobj->mDColsP[sk]->GetCstSegment(iseg), sz);
[2820]146 break;
[2846]147 case BaseDataTable::ComplexField :
148 if (tbltyp == BINARY_TBL) {
149 icol++;
150 FitsBlockRW< complex<r_4> >::WriteColumnData(os, icol, l+1, 1,
[2889]151 dobj->mYColsP[sk]->GetCstSegment(iseg), sz);
[2846]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,
[2889]158 dobj->mZColsP[sk]->GetCstSegment(iseg), sz);
[2846]159 }
160 break;
161 case BaseDataTable::StringField :
162 icol++;
163 FitsBlockRW<std::string>::WriteColumnData(os, icol, l+1, 1,
[2889]164 dobj->mSColsP[sk]->GetCstSegment(iseg), sz);
[2846]165 break;
[2820]166 default:
167 break;
168 }
169 }
170 }
[2889]171
172 // Ecriture de SegmentSize et autre elements de DVList
[2820]173 os.WriteHeaderRecords(dobj->Info());
174 MuTyV mtv = dobj->SegmentSize();
175 os.WriteKey("SEGMSIZE",mtv," SOPHYA::DataTable SegmentSize");
[2846]176 mtv = "SOPHYA::DataTable";
177 os.WriteKey("SOPCLSNM",mtv," Object class name ");
[2820]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
[2889]190 // Determination de la taille de segment
[3069]191 sa_size_t segsz = is.GetNbRows() / 64; // Taille de segment par defaut
[2820]192 if (segsz > 2048) segsz = 2048;
193 string key = "SEGMSIZE";
[2846]194 bool knex = false;
195 string ssegsz = is.KeyValue(key, knex);
[3069]196 bool fgsss = false;
197 if (!knex && (ssegsz.length() > 0)) { segsz = atoi(ssegsz.c_str()); fgsss = true; }
[2820]198 if (segsz < 16) segsz = 16;
199
[2889]200 // Nb de lignes et de colonnes
201 vector<string> colnames;
202 vector<int> coltypes;
[3167]203 vector<LONGLONG> repcnt, width;
204 vector<sa_size_t> colpos;
[2889]205 is.GetColInfo(colnames, coltypes, repcnt, width);
[3167]206 int_8 nbrows = is.GetNbRows();
[2889]207
[2820]208 if (dobj == NULL) { // On cree la table si besoin
[3069]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
[2889]214 string key = "SOPCLSNM";
215 string clsnm = is.KeyValue(key);
[3069]216 if ( (clsnm == "SOPHYA::SwFitsDataTable") || (nbrows*colnames.size() < 10000000) )
[2889]217 dobj = new DataTable(segsz);
[3069]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);
[2820]227 }
228 else {
229 dobj->Clear(); // On efface la table sinon
[3069]230 if (fgsss) dobj->mSegSz = segsz;
[2820]231 }
232
[2889]233 // Type reel de table
[2820]234 DataTable* dt = dynamic_cast< DataTable *> (dobj);
[2889]235 SwFitsDataTable* swfdt = dynamic_cast< SwFitsDataTable *> (dobj);
236
237 vector<int_8> swpos;
[3069]238 segsz = dobj->mSegSz;
239 int_8 swp = 1;
240 while (swp < nbrows) {
241 swpos.push_back(swp); swp += segsz;
242 }
[2889]243 // Initialize the fits swap stream for SwFitsDataTable if necessary
244 if (swfdt) {
[3069]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());
[2889]249 swfdt->FitsSwapFile().ShareFitsPtr(is);
250 }
251 }
252
[2820]253 // --ATTENTION-- repcnt (contenu=vecteur) pas pris en compte pour le moment
254 for(sa_size_t k=0; k<colnames.size(); k++) {
[2963]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
[2820]260 switch ( coltypes[k] ) {
261 case TBYTE :
262 case TSHORT :
263 case TUSHORT :
264 case TINT :
[2889]265 if (swfdt)
266 swfdt->AddColRd(BaseDataTable::IntegerField, colnames[k], k+1, &swpos);
267 else dobj->AddIntegerColumn(colnames[k]);
[2820]268 colpos.push_back(k+1);
269 break;
270 case TUINT:
271 case TLONG :
272 case TULONG :
273#ifdef TLONGLONG
274 case TLONGLONG :
[2889]275#endif
276 if (swfdt)
277 swfdt->AddColRd(BaseDataTable::LongField, colnames[k], k+1, &swpos);
278 else dobj->AddLongColumn(colnames[k]);
[2820]279 colpos.push_back(k+1);
280 break;
281 case TFLOAT :
[2889]282 if (swfdt)
283 swfdt->AddColRd(BaseDataTable::FloatField, colnames[k], k+1, &swpos);
284 else dobj->AddFloatColumn(colnames[k]);
[2820]285 colpos.push_back(k+1);
286 break;
287 case TDOUBLE :
[2889]288 if (swfdt)
289 swfdt->AddColRd(BaseDataTable::DoubleField, colnames[k], k+1, &swpos);
290 else dobj->AddDoubleColumn(colnames[k]);
[2820]291 colpos.push_back(k+1);
292 break;
[2846]293 case TCOMPLEX :
[2889]294 if (swfdt)
295 swfdt->AddColRd(BaseDataTable::ComplexField, colnames[k], k+1, &swpos);
296 else dobj->AddComplexColumn(colnames[k]);
[2846]297 colpos.push_back(k+1);
298 break;
299 case TDBLCOMPLEX :
[2889]300 if (swfdt)
301 swfdt->AddColRd(BaseDataTable::DoubleComplexField, colnames[k], k+1, &swpos);
302 else dobj->AddDoubleComplexColumn(colnames[k]);
[2846]303 colpos.push_back(k+1);
304 break;
305 case TSTRING :
[2889]306 if (swfdt)
307 swfdt->AddColRd(BaseDataTable::StringField, colnames[k], k+1, &swpos);
308 else dobj->AddStringColumn(colnames[k]);
[2846]309 colpos.push_back(k+1);
310 break;
[2820]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();
[2889]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
[3069]324 if (swfdt) {
325 swfdt->mNSeg = swpos.size();
326 return;
327 }
[2889]328
[2820]329 while ((dobj->SegmentSize()*dobj->NbSegments()) < dobj->NEntry())
330 dobj->Extend();
[2846]331 //DBG cout << " DBG2 -- dobj->mNSeg = " << dobj->NbSegments() << " SegSize="
332 //DBG << dobj->SegmentSize() << " NEntry=" << dobj->NEntry() << endl;
[2820]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,
[2889]347 dobj->mIColsP[sk]->GetSegment(iseg), sz);
[2820]348 break;
349 case BaseDataTable::LongField :
350 FitsBlockRW<int_8>::ReadColumnData(is, icol, l+1, 1,
[2889]351 dobj->mLColsP[sk]->GetSegment(iseg), sz);
[2820]352 break;
353 case BaseDataTable::FloatField :
354 FitsBlockRW<r_4>::ReadColumnData(is, icol, l+1, 1,
[2889]355 dobj->mFColsP[sk]->GetSegment(iseg), sz);
[2820]356 break;
357 case BaseDataTable::DoubleField :
[2846]358 case BaseDataTable::DateTimeField :
[2820]359 FitsBlockRW<r_8>::ReadColumnData(is, icol, l+1, 1,
[2889]360 dobj->mDColsP[sk]->GetSegment(iseg), sz);
[2820]361 break;
[2846]362 case BaseDataTable::ComplexField :
363 FitsBlockRW< complex<r_4> >::ReadColumnData(is, icol, l+1, 1,
[2889]364 dobj->mYColsP[sk]->GetSegment(iseg), sz);
[2846]365 break;
366 case BaseDataTable::DoubleComplexField :
367 FitsBlockRW< complex<r_8> >::ReadColumnData(is, icol, l+1, 1,
[2889]368 dobj->mZColsP[sk]->GetSegment(iseg), sz);
[2846]369 break;
370 case BaseDataTable::StringField :
371 FitsBlockRW<std::string>::ReadColumnData(is, icol, l+1, 1,
[2889]372 dobj->mSColsP[sk]->GetSegment(iseg), sz);
[2846]373 break;
[2820]374 default:
375 break;
376 }
377 }
378 }
379
380}
381
382
[3237]383} // FIN namespace SOPHYA
[2820]384
385
Note: See TracBrowser for help on using the repository browser.