4
* This holds the handlers for all of the fitsObj commands
9
* ------------------------------------------------------------
10
* MODIFICATION HISTORY:
11
* 2004-02-05 Ziqin Pan:
12
* Add the following commands:
13
* 1. delete row -rowrange rangelist
14
* 2. add column colName colForm ?expr? ?rowrange?
15
* 3. select rows -expr expression firstrow nrow
20
#include "fitsTclInt.h"
22
#define ARGV_STR(x) Tcl_GetStringFromObj(argv[x],NULL)
25
* ------------------------------------------------------------
29
* This is the dispatch routine for the Fits objects
37
* ------------------------------------------------------------
40
int fitsDispatch( ClientData clientData,
43
Tcl_Obj *const argv[] )
46
static char *commandList =
47
"Available commands:\n"
48
"close - close the file and delete this object\n"
49
"move ?+/-?n - move to HDU #n or forward/backward +/-n HDUs\n"
50
"dump ?-s/-e/-l? - return contents of the CHDU's header in various formats\n"
51
"info - get information about the CHDU \n"
52
"get - get various data from CHDU\n"
53
"put - change contents of CHDU: keywords or extension data\n"
54
"insert- insert KEYWORDs, COLUMNs, ROWs, or HDUs \n"
55
"delete- delete KEYWORDs, COLUMNs, ROWs, or HDUs \n"
56
"select- select ROWs \n"
57
"load - load image and table data into variables or pointers \n"
58
"free - free loaded data. **If the address is not the right one\n"
59
" returned from \"load xxx\", a core dump will occur** \n"
60
"flush ?clear? - flush dirty buffers to disk (also clear buffer contents?) \n"
61
"copy filename - copy the CHDU to a new file\n"
62
"sascii- save extension contents to an ascii file \n"
63
"sort - sort the CHDU according to supplied parameters \n"
64
"add - Append new columns and rows to table. Column may be filled\n"
65
" with the results of a supplied arithmetic expression\n"
66
"append filename - Append current HDU to indicated fits file\n"
67
"histogram - Create N-D histogram from table columns\n"
68
"smooth - Create a smoothed image from the original image.\n"
69
"checksum update|verify - Update or verify checksum keywords of the\n"
70
" current HDU. Verify: 1=good, -1=bad, 0=none\n"
74
FitsFD *curFile = (FitsFD *) clientData;
78
int (*fct)(FitsFD*,int,Tcl_Obj*const[]);
80
{ "close", 1, fitsTcl_close },
81
{ "move", 1, fitsTcl_move },
82
{ "dump", 1, fitsTcl_dump },
83
{ "info", 0, fitsTcl_info },
84
{ "get", 0, fitsTcl_get },
85
{ "put", 1, fitsTcl_put },
86
{ "insert", 0, fitsTcl_insert },
87
{ "delete", 0, fitsTcl_delete },
88
{ "select", 0, fitsTcl_select },
89
{ "load", 0, fitsTcl_load },
90
{ "free", 1, fitsTcl_free },
91
{ "flush", 1, fitsTcl_flush },
92
{ "copy", 1, fitsTcl_copy },
93
{ "sascii", 0, fitsTcl_sascii },
94
{ "sort", 0, fitsTcl_sort },
95
{ "add", 0, fitsTcl_add },
96
{ "append", 1, fitsTcl_append },
97
{ "histogram",1, fitsTcl_histo },
98
{ "create", 1, fitsTcl_create },
99
{ "smooth", 1, fitsTcl_smooth },
100
{ "checksum", 1, fitsTcl_checksum },
106
* If there are no arguments, return the help string
110
Tcl_SetResult(interp,commandList,TCL_STATIC);
115
* Search for the command and call its handler
119
cmd = Tcl_GetStringFromObj( argv[1], NULL );
120
for( i=0; cmdLookup[i].cmd[0]; i++ ) {
121
if( !strcmp( cmdLookup[i].cmd, cmd ) ) {
123
if( cmdLookup[i].tclObjs ) {
124
status = (*cmdLookup[i].fct)(curFile, argc, argv);
128
* Convert TCL_OBJs to strings
131
args = (char **) ckalloc( argc * sizeof(char *) );
132
for( j=0; j<argc; j++ ) {
133
args[j] = Tcl_GetStringFromObj( argv[j], NULL );
135
status = (*cmdLookup[i].fct)(curFile, argc, (Tcl_Obj**)args);
136
ckfree( (char*) args );
144
* NO SUCH COMMAND... Error
147
Tcl_SetResult(interp, "Unrecognized command\n", TCL_STATIC);
148
Tcl_AppendResult(interp, commandList);
154
/**********************
156
* Command Handlers....
158
**********************/
161
/******************************************************************
163
******************************************************************/
165
int fitsTcl_close( FitsFD *curFile, int argc, Tcl_Obj *const argv[] )
168
Tcl_SetResult(curFile->interp,
169
"Wrong number of args: expected fits close",TCL_STATIC);
172
if( Tcl_DeleteCommand( curFile->interp, curFile->handleName ) != TCL_OK ) {
175
curFile->fptr = NULL;
176
curFile->handleName = NULL;
181
/******************************************************************
183
******************************************************************/
185
int fitsTcl_move( FitsFD *curFile, int argc, Tcl_Obj *const argv[] )
187
static char *moveList = "\n"
188
"move nmove - moves the CHDU: \n"
189
" nmove = +- -> relative move, otherwise absolute\n"
190
" returns hdutype\n";
198
Tcl_SetResult(curFile->interp, moveList, TCL_STATIC);
202
/* Convert the nmove argument */
204
if( Tcl_GetIntFromObj(curFile->interp,argv[2],&nmove) != TCL_OK ) {
205
Tcl_SetResult(curFile->interp,"Wrong type for nmove",TCL_STATIC);
210
pStr = Tcl_GetStringFromObj( argv[3], NULL );
211
if( !strcmp(pStr, "-s") ) {
214
Tcl_SetResult(curFile->interp, "fitsTcl Error: "
215
"unkown option: -s for load without read header", TCL_STATIC);
220
pStr = Tcl_GetStringFromObj( argv[2], NULL );
223
if ( strchr(pStr,'+') ) {
224
status = fitsJustMoveHDU(curFile, nmove, 1);
225
} else if ( strchr(pStr,'-') ) {
226
status = fitsJustMoveHDU(curFile, nmove,-1);
228
status = fitsJustMoveHDU(curFile, nmove, 0);
233
if ( strchr(pStr,'+') ) {
234
status = fitsMoveHDU(curFile, nmove, 1);
235
} else if ( strchr(pStr,'-') ) {
236
status = fitsMoveHDU(curFile, nmove,-1);
238
status = fitsMoveHDU(curFile, nmove, 0);
247
/* Return the hdutype */
248
Tcl_SetObjResult(curFile->interp,
249
Tcl_NewIntObj( curFile->hduType ) );
254
/******************************************************************
256
******************************************************************/
258
int fitsTcl_dump( FitsFD *curFile, int argc, Tcl_Obj *const argv[] )
265
status = fitsDumpHeader(curFile);
269
option = Tcl_GetStringFromObj( argv[2], NULL );
270
if( !strcmp("-l",option) ) {
271
status = fitsDumpKwdsToList(curFile);
272
} else if( !strcmp("-s",option) ) {
273
status = fitsDumpHeaderToKV(curFile);
274
} else if( !strcmp("-e",option) ) {
275
status = fitsDumpHeaderToCard(curFile);
277
Tcl_SetResult(curFile->interp,
278
"Usage: fitsFile dump ?-s/-e/-l?", TCL_STATIC);
288
/******************************************************************
290
******************************************************************/
292
int fitsTcl_info( FitsFD *curFile, int argc, char *const argv[] )
294
static char *infoList = "\n"
295
"Available Commands:\n"
297
"info chdu - returns the CHDU\n"
298
"info nhdu - returns the total number of hdu in the file\n"
299
"info filesize- returns the size of the file(in unit of 2880 byte)\n"
300
"info hdutype - returns the type of the CHDU\n"
301
"info imgType - returns the image type of the CHDU \n"
302
"info imgdim - returns the image dimension of the CHDU \n"
303
"info ncols - returns the number of columns in the CHDU\n"
304
"info nrows - returns the number of rows in the CHDU\n"
305
"info nkwds - returns the number of keywords in the CHDU\n"
306
"info column ?-exact? ?colNames? \n"
307
" with no argument, lists the columns,\n"
308
" otherwise gives more info about columns in colName\n"
309
" ?-minmax? colName firstElement ?rowRange? \n"
311
" ?-stat? colName firstElement ?rowRange? \n"
312
" statistics about the indicated column\n"
315
int i, j, felem, numRange, *range=NULL;
316
int numCols, colTypes[FITS_COLMAX], colNums[FITS_COLMAX], strSize[FITS_COLMAX];
319
char tmpStr[3][FLEN_VALUE]; /* Some general purpose string buffers */
320
char *mrgList[9], *pattern, *tmpStrPtr;
321
char errMsg[256], **colList;
322
Tcl_DString concatList;
325
Tcl_SetResult(curFile->interp, infoList, TCL_STATIC);
330
/* check if the chdu has been loaded or not */
332
if( curFile->CHDUInfo.table.loadStatus != 1 ) {
334
Tcl_SetResult(curFile->interp,
335
"You need to load the CHDU first", TCL_STATIC);
340
if( !strcmp("chdu",argv[2] ) ) {
342
sprintf(result,"%d",curFile->chdu);
343
Tcl_SetResult(curFile->interp, result, TCL_VOLATILE);
345
} else if( !strcmp("imgType",argv[2]) ) {
350
fits_get_img_dim(curFile->fptr, &naxis, &status);
353
fits_get_img_size(curFile->fptr, naxis, naxes, &status);
356
fits_get_img_type(curFile->fptr, &bitpix, &status);
358
sprintf(result,"%d", bitpix);
359
Tcl_SetResult(curFile->interp, result, TCL_VOLATILE);
361
} else if( !strcmp("filesize",argv[2]) ) {
363
sprintf(result,"%lld",curFile->fptr->Fptr->filesize/2880);
364
Tcl_SetResult(curFile->interp, result, TCL_VOLATILE);
366
} else if( !strcmp("hdutype",argv[2]) ) {
368
switch ( curFile->hduType ) {
371
tmpStrPtr = "Image extension";
373
tmpStrPtr = "Primary array";
376
tmpStrPtr = "ASCII Table";
379
tmpStrPtr = "Binary Table";
382
Tcl_SetResult(curFile->interp, "Unsupported hdu type", TCL_STATIC);
386
Tcl_SetResult(curFile->interp, tmpStrPtr, TCL_STATIC);
388
} else if( !strcmp("nhdu", argv[2]) ) {
391
ffthdu(curFile->fptr, &nhdu, &status);
393
dumpFitsErrStack(curFile->interp, status);
396
sprintf(result, "%d", nhdu);
397
Tcl_SetResult( curFile->interp, result, TCL_VOLATILE );
399
} else if( !strcmp("nkwds",argv[2] ) ) {
401
sprintf(result, "%-d", curFile->numKwds);
402
Tcl_SetResult( curFile->interp, result, TCL_VOLATILE );
404
} else if( !strcmp("ncols",argv[2] ) ) {
406
if (curFile->hduType == IMAGE_HDU ) {
407
Tcl_SetResult( curFile->interp,
408
"No columns for an Image extension", TCL_STATIC);
411
sprintf(result, "%d", curFile->CHDUInfo.table.numCols);
412
Tcl_SetResult( curFile->interp, result, TCL_VOLATILE );
414
} else if( !strcmp("nrows",argv[2] ) ) {
416
if (curFile->hduType == IMAGE_HDU ) {
417
Tcl_SetResult( curFile->interp,
418
"No rows for an Image extension", TCL_STATIC );
421
sprintf(result,"%lld",curFile->CHDUInfo.table.numRows);
422
Tcl_SetResult( curFile->interp, result, TCL_VOLATILE );
424
} else if( !strcmp("column",argv[2] ) ) {
426
if( curFile->hduType == IMAGE_HDU ) {
427
Tcl_SetResult( curFile->interp,
428
"No Columns in an image extension", TCL_STATIC );
434
/***********************************
435
* Return a list of column names *
436
***********************************/
438
for ( i = 0; i < curFile->CHDUInfo.table.numCols; i++ ) {
439
Tcl_AppendElement(curFile->interp,
440
curFile->CHDUInfo.table.colName[i]);
445
/*******************************************
446
* Return info about one or more columns *
447
*******************************************/
449
if( !strcmp(argv[3], "-stat") ) {
452
Tcl_SetResult(curFile->interp,
453
"Usage: info column -stat columnName ?felem? ?rows?",
460
} else if( Tcl_GetInt(curFile->interp, argv[5], &felem)
466
numRange = fitsParseRangeNum(argv[6])+1;
467
range = (int*) malloc(numRange*2*sizeof(int));
468
if( fitsParseRange(argv[6],&numRange,range,numRange,
469
1, curFile->CHDUInfo.table.numRows,errMsg)
471
Tcl_SetResult(curFile->interp,
472
"Error parsing row range:\n", TCL_STATIC);
473
Tcl_AppendResult(curFile->interp, errMsg, (char*)NULL);
478
range = (int*) malloc(numRange*2*sizeof(int));
480
range[1] = curFile->CHDUInfo.table.numRows ;
483
if( fitsTransColList( curFile, argv[4], &numCols,
484
colNums, colTypes, strSize) != TCL_OK )
487
if( fitsColumnStatistics(curFile,colNums[0],felem,
488
numRange,range) != TCL_OK ) {
492
} else if( !strcmp(argv[3], "-minmax") ) {
495
Tcl_SetResult(curFile->interp,
496
"Usage: info column -minmax "
497
"columnName ?felem? ?rows?", TCL_STATIC);
503
} else if( Tcl_GetInt(curFile->interp, argv[5], &felem)
509
numRange = fitsParseRangeNum(argv[6])+1;
510
range = (int*) malloc(numRange*2*sizeof(int));
511
if( fitsParseRange(argv[6],&numRange,range,numRange,
512
1, curFile->CHDUInfo.table.numRows,errMsg)
514
Tcl_SetResult(curFile->interp,
515
"Error parsing row range:\n", TCL_STATIC);
516
Tcl_AppendResult(curFile->interp, errMsg, (char*)NULL);
521
range = (int*) malloc(numRange*2*sizeof(int));
523
range[1] = curFile->CHDUInfo.table.numRows ;
526
for ( i = 0; i < curFile->CHDUInfo.table.numCols; i++) {
527
if( !strcasecmp(argv[4],curFile->CHDUInfo.table.colName[i]) ) {
528
if( fitsColumnMinMax(curFile, i+1, felem, numRange, range)
536
} else if( !strcmp(argv[3], "-exact") ) {
538
/*************************************************************
539
* Return Info about Columns matching an exact column name *
540
*************************************************************/
543
Tcl_SetResult(curFile->interp,
544
"Usage: info column -exact columnNames",
548
if( fitsTransColList( curFile, argv[4], &numCols,
549
colNums, colTypes, strSize) != TCL_OK )
552
for ( i = 0; i < numCols; i++ ) {
554
mrgList[0] = curFile->CHDUInfo.table.colName[j];
555
mrgList[1] = curFile->CHDUInfo.table.colType[j];
556
mrgList[2] = curFile->CHDUInfo.table.colUnit[j];
557
mrgList[3] = curFile->CHDUInfo.table.colDisp[j];
558
mrgList[4] = curFile->CHDUInfo.table.colFormat[j];
559
sprintf(tmpStr[0], "%d",
560
curFile->CHDUInfo.table.colWidth[j]);
561
mrgList[5] = tmpStr[0];
562
sprintf(tmpStr[1], "%d",
563
curFile->CHDUInfo.table.colTzflag[j]);
564
mrgList[6] = tmpStr[1];
565
sprintf(tmpStr[2], "%d",
566
curFile->CHDUInfo.table.colTsflag[j]);
567
mrgList[7] = tmpStr[2];
568
mrgList[8] = curFile->CHDUInfo.table.colNull[j];
569
Tcl_AppendElement(curFile->interp,Tcl_Merge(9,mrgList));
572
} else if( argc==4 ) {
574
/***********************************************************
575
* Return Info about Columns matching regular expression *
576
***********************************************************/
578
Tcl_DStringInit(&concatList);
580
if( Tcl_SplitList(curFile->interp, argv[3], &numCols,
581
&colList) != TCL_OK ) {
585
if( fitsMakeRegExp(curFile->interp, numCols, colList,
588
Tcl_SetResult(curFile->interp,
589
"Error making up reg expr", TCL_STATIC);
590
Tcl_DStringFree(&concatList);
591
ckfree((char*)colList);
594
ckfree((char*)colList);
595
pattern = Tcl_DStringValue(&concatList);
596
for ( i = 0; i < curFile->CHDUInfo.table.numCols; i++) {
597
strToUpper(curFile->CHDUInfo.table.colName[i], &tmpStrPtr);
598
status = Tcl_RegExpMatch(curFile->interp, tmpStrPtr, pattern);
599
ckfree( (char*)tmpStrPtr );
601
mrgList[0] = curFile->CHDUInfo.table.colName[i];
602
mrgList[1] = curFile->CHDUInfo.table.colType[i];
603
mrgList[2] = curFile->CHDUInfo.table.colUnit[i];
604
mrgList[3] = curFile->CHDUInfo.table.colDisp[i];
605
mrgList[4] = curFile->CHDUInfo.table.colFormat[i];
606
sprintf(tmpStr[0], "%d",
607
curFile->CHDUInfo.table.colWidth[i]);
608
mrgList[5] = tmpStr[0];
609
sprintf(tmpStr[1], "%d",
610
curFile->CHDUInfo.table.colTzflag[i]);
611
mrgList[6] = tmpStr[1];
612
sprintf(tmpStr[2], "%d",
613
curFile->CHDUInfo.table.colTsflag[i]);
614
mrgList[7] = tmpStr[2];
615
mrgList[8] = curFile->CHDUInfo.table.colNull[i];
616
Tcl_AppendElement(curFile->interp,Tcl_Merge(9,mrgList));
617
} else if( status == -1 ) {
618
Tcl_AppendResult(curFile->interp,"Error, ", pattern,
619
" not a Regular Expression.",
621
Tcl_DStringFree(&concatList);
625
Tcl_DStringFree(&concatList);
629
Tcl_SetResult(curFile->interp,
631
" info column ?-exact? colNames \n"
632
" -minmax colName firstElement ?rowRange? \n"
633
" -stat colName firstElement ?rowRange? \n",
640
/* End of 'info column' */
642
} else if( !strcmp("expr", argv[2]) ) {
644
if( curFile->hduType == IMAGE_HDU ) {
645
Tcl_SetResult(curFile->interp,"Not a table extension", TCL_STATIC);
649
Tcl_SetResult(curFile->interp,
650
"Usage: info expr exprStr", TCL_STATIC);
654
if( exprGetInfo( curFile, argv[3] ) ) {
658
} else if( !strcmp("imgdim", argv[2]) ) {
660
if ( curFile->hduType != IMAGE_HDU ) {
661
Tcl_SetResult(curFile->interp,
662
"Current extension is not an image", TCL_STATIC);
666
Tcl_ResetResult(curFile->interp);
667
for (i=0; i < curFile->CHDUInfo.image.naxes; i++) {
668
sprintf(tmpStr[0], "%lld", curFile->CHDUInfo.image.naxisn[i]);
669
Tcl_AppendElement(curFile->interp, tmpStr[0]);
674
Tcl_SetResult(curFile->interp,
675
"Unrecognized option to info", TCL_STATIC);
680
if (range) free(range);
685
/******************************************************************
687
******************************************************************/
689
int fitsTcl_get( FitsFD *curFile, int argc, char *const argv[] )
691
static char *getList = "\n"
692
"Available Commands:\n"
693
"get keyword ?keyName? - displays the keyword(s) keyname\n"
694
" - keywords are specified by reg. expression\n"
695
"get keyword -num keyNum - displays the num th keyword in the CHDU\n"
696
"get wcs ?RAcol DECcol?\n"
697
" - return a list of the WCS parameters for either a table or image:\n"
698
" {xrval yrval xrpix yrpix xinc yinc rot ctype}\n"
699
" For a table, supply RAcol and DECcol which are column names or \n"
700
" numbers of the RA column and DEC column\n"
701
"get header2str - get header and construct it into a string\n"
702
"get translatedKeywords - translated header keyword to normal one.\n"
703
"get dummy2str - create dummy fits image file and get header and construct it into a string\n"
704
"get image ?firstElem? ?numElem?\n"
705
" - return elements of an image\n"
706
"get table ?-c? ?-noformat? ?colList? ?rowList?\n"
707
" - return the elements rowList from list colList\n"
708
" - if no rowList is provided, give all rows\n"
709
" - if no colList is provided, give all columns\n"
710
" - use colList = * for all columns\n"
711
" - -c means return each column as a seperate list.\n"
712
"get vtable ?-noformat? colname firstelement ?rowList?\n"
713
" - get the firstelement-th vector element\n"
716
char Comment[FLEN_COMMENT], Name[FLEN_KEYWORD], Value[FLEN_VALUE];
717
int numCols,colNums[FITS_COLMAX],colTypes[FITS_COLMAX],strSize[FITS_COLMAX];
718
int numRange, *range=NULL;
719
Tcl_HashEntry *newEntry;
720
Tcl_HashSearch search;
721
Tcl_DString concatList, regExpList;
722
Tcl_DString ** colDString;
723
FitsCardList *curCard;
727
int bycol,niters,fRow;
735
Tcl_Obj *resObj, **valArray, *listObj, **listArray, *valObj;
737
listObj = Tcl_NewObj();
740
Tcl_SetResult(curFile->interp, getList, TCL_STATIC);
744
if( !strcmp("keyword", argv[2]) ) {
750
Tcl_DStringInit(&concatList);
752
newEntry = Tcl_FirstHashEntry(curFile->kwds,&search);
754
newKwd = (Keyword *) Tcl_GetHashValue(newEntry);
755
Tcl_DStringStartSublist(&concatList);
756
Tcl_DStringAppendElement(&concatList,newKwd->name);
757
Tcl_DStringAppendElement(&concatList,newKwd->value);
758
Tcl_DStringAppendElement(&concatList,newKwd->comment);
759
Tcl_DStringEndSublist(&concatList);
760
newEntry = Tcl_NextHashEntry(&search);
762
Tcl_DStringResult(curFile->interp,&concatList);
764
} else if( !strcmp(argv[3],"-num") ) {
767
Tcl_SetResult(curFile->interp,
768
"Wrong number of args, expected get keyword "
769
"-num number", TCL_STATIC);
773
if( Tcl_GetInt(curFile->interp,argv[4],&nmove) != TCL_OK ) {
774
Tcl_AppendResult(curFile->interp,
775
"\nWrong type for nmove",(char *) NULL);
780
* First look through the comments and the history cards:
781
* remember the first card is always a dummy...
784
curCard = (curFile->hisHead)->next;
786
if ( curCard->pos == nmove ) {
787
Tcl_AppendElement(curFile->interp,"HISTORY");
788
Tcl_AppendElement(curFile->interp," ");
789
Tcl_AppendElement(curFile->interp,curCard->value);
792
curCard = curCard->next;
795
curCard = (curFile->comHead)->next;
797
if ( curCard->pos == nmove ) {
798
Tcl_AppendElement(curFile->interp,"COMMENT");
799
Tcl_AppendElement(curFile->interp," ");
800
Tcl_AppendElement(curFile->interp,curCard->value);
803
curCard = curCard->next;
806
newEntry = Tcl_FirstHashEntry(curFile->kwds,&search);
808
newKwd = (Keyword *) Tcl_GetHashValue(newEntry);
809
if ( newKwd->pos == nmove ) {
810
Tcl_AppendElement(curFile->interp,newKwd->name);
811
Tcl_AppendElement(curFile->interp,newKwd->value);
812
Tcl_AppendElement(curFile->interp,newKwd->comment);
815
newEntry = Tcl_NextHashEntry(&search);
818
/* The Hashes all failed (maybe duplicate keys in header. */
819
/* Go directly to file. */
820
ffgkyn( curFile->fptr, nmove, Name, Value, Comment, &status);
822
dumpFitsErrStack(curFile->interp,status);
825
Tcl_AppendElement(curFile->interp,Name);
826
Tcl_AppendElement(curFile->interp,Value);
827
Tcl_AppendElement(curFile->interp,Comment);
831
Tcl_DStringInit(®ExpList);
833
if( fitsMakeRegExp(curFile->interp, argc-3, argv+3, ®ExpList, 1)
835
Tcl_SetResult(curFile->interp,
836
"Error building regular expression", TCL_STATIC);
837
Tcl_DStringFree(®ExpList);
841
pattern = Tcl_DStringValue(®ExpList);
843
Tcl_DStringInit(&concatList);
846
newEntry = Tcl_FirstHashEntry(curFile->kwds,&search);
847
while ( NULL != newEntry ) {
848
newKwd = (Keyword *) Tcl_GetHashValue(newEntry);
849
status = Tcl_RegExpMatch(curFile->interp,newKwd->name,pattern);
852
Tcl_DStringStartSublist(&concatList);
853
Tcl_DStringAppendElement(&concatList,newKwd->name);
854
Tcl_DStringAppendElement(&concatList,newKwd->value);
855
Tcl_DStringAppendElement(&concatList,newKwd->comment);
856
Tcl_DStringEndSublist(&concatList);
857
newEntry = Tcl_NextHashEntry(&search);
858
} else if ( status == -1 ) {
859
Tcl_AppendResult(curFile->interp,"The Pattern: ",pattern,
860
" is not a regular expression."
862
Tcl_DStringFree(&concatList);
863
Tcl_DStringFree(®ExpList);
866
newEntry = Tcl_NextHashEntry(&search);
871
Tcl_SetResult(curFile->interp,
872
"No matching keywords found/or keyword not loaded",
874
Tcl_DStringFree(&concatList);
878
Tcl_DStringResult(curFile->interp,&concatList);
881
} else if( !strcmp("wcs", argv[2]) ) {
885
if ( curFile->hduType == IMAGE_HDU ) {
887
/* Get WCS from Image extension */
889
if( argc < 4 || argc > 5 ) {
890
Tcl_SetResult(curFile->interp,
891
"For image extension use, get wcs", TCL_STATIC);
895
if ( argc == 5 && !strcmp("-m", argv[3]) ) {
896
if( fitsGetWcsMatrix(curFile, 0, NULL, argv[4][0]) != TCL_OK ) {
900
if( fitsGetWcsPair(curFile,0,0, '\0') != TCL_OK ) {
907
/* Get WCS from Table extension */
912
int columns[FITS_MAXDIMS];
914
if( argc>4 && !strcmp("-m", argv[3]) ) {
918
Tcl_SetResult(curFile->interp,
919
"For table extension use, "
920
"get wcs -m dest Col1 ?Col2 ...?",
923
} else if( nCols > FITS_MAXDIMS ) {
924
Tcl_SetResult(curFile->interp,
925
"Too many columns to obtain WCS information",
932
Tcl_SetResult(curFile->interp,
933
"For table extension use, get wcs -m dest RAcol DecCol",
939
for( j=0, i=argc-nCols; i<argc; i++,j++ ) {
941
if( Tcl_GetInt(curFile->interp, argv[i], columns+j) != TCL_OK ) {
942
Tcl_ResetResult(curFile->interp);
943
if( fitsTransColList( curFile, argv[i],
944
&numCols, colNums, colTypes, strSize)
946
Tcl_SetResult(curFile->interp,
947
"Unable to read column specifier", TCL_STATIC);
951
Tcl_SetResult(curFile->interp,
952
"Can only have column value", TCL_STATIC);
955
columns[j] = colNums[0];
961
if( fitsGetWcsMatrix(curFile, nCols, columns, argv[4][0]) != TCL_OK ) {
965
if( fitsGetWcsPair(curFile, columns[0], columns[1], argv[4][0]) != TCL_OK ) {
972
} else if( !strcmp("dummy2str", argv[2]) ) {
978
int columns[FITS_MAXDIMS];
983
/* Pan Chai: there is only 2 columns */
990
for( j=0, i=argc-nCols; i<argc; i++,j++ ) {
992
if( Tcl_GetInt(curFile->interp, argv[i], columns+j) != TCL_OK ) {
993
Tcl_ResetResult(curFile->interp);
994
if( fitsTransColList( curFile, argv[i],
995
&numCols, colNums, colTypes, strSize)
997
Tcl_SetResult(curFile->interp,
998
"Unable to read column specifier", TCL_STATIC);
1001
if( numCols != 1 ) {
1002
Tcl_SetResult(curFile->interp,
1003
"Can only have column value", TCL_STATIC);
1006
columns[j] = colNums[0];
1010
/* size of histogram is now known, so create temp output file */
1011
if (ffinit(&dummyptr, "mem://", &status) > 0)
1013
ffpmsg("failed to create temp output file for dummy fits file");
1018
/* create output FITS image HDU */
1019
if (ffcrim(dummyptr, bitpix, naxis, naxes, &status) > 0)
1021
ffpmsg("failed to create output dummy FITS image");
1027
/* copy header keywords, converting pixel list WCS keywords to image WCS form */
1028
if (fits_copy_pixlist2image(curFile->fptr, dummyptr, 9, naxis, columns, &status) > 0)
1030
ffpmsg("failed to copy pixel list keywords to new dummy header");
1035
if ( ffhdr2str(dummyptr, 1, (char **)NULL, 0, &header, &nkeys, &status) > 0 ) {
1036
Tcl_SetResult(curFile->interp, "Failed to collect all the headers.", TCL_STATIC);
1040
/* since this is a dummy header, all relative reference starts with 1 */
1041
for (i = 0; i < naxis; i++) {
1045
fitsFileGetWcsMatrix( curFile, dummyptr, naxis, columns, argv[3][0], data);
1047
Tcl_ListObjAppendElement( curFile->interp, listObj, Tcl_NewStringObj(header, -1));
1048
Tcl_ListObjAppendElement( curFile->interp, listObj, Tcl_NewIntObj( nkeys ) );
1049
Tcl_ListObjAppendElement( curFile->interp, listObj, Tcl_NewListObj(5,data) );
1050
Tcl_SetObjResult(curFile->interp, listObj);
1055
} else if( !strcmp("translatedKeywords", argv[2]) ) {
1056
char outfile[FLEN_FILENAME];
1062
Tcl_SetResult(curFile->interp,
1063
"Usage: get translatedKeywords rownum colname",
1068
strcpy(outfile, "mem://_1");
1070
/* Copy the image into new primary array and open it as the current */
1071
/* fptr. This will close the table that contains the original image. */
1073
/* create new empty file to hold copy of the image */
1074
if (ffinit(&newptr, outfile, &status) > 0)
1076
ffpmsg("failed to create file for copy of image in table cell:");
1081
rownum = atol(argv[4]);
1083
if (fits_copy_cell2image(curFile->fptr, newptr, argv[3], rownum, &status) > 0)
1086
ffpmsg("Failed to copy table cell to new primary array:");
1087
ffclos(curFile->fptr, &status2);
1088
curFile->fptr = 0; /* return null file pointer */
1092
if ( ffhdr2str(newptr, 1, (char **)NULL, 0, &header, &nkeys, &status) > 0 ) {
1093
Tcl_SetResult(curFile->interp, "Failed to collect all the headers.", TCL_STATIC);
1097
Tcl_ListObjAppendElement( curFile->interp, listObj, Tcl_NewStringObj(header, -1));
1098
Tcl_ListObjAppendElement( curFile->interp, listObj, Tcl_NewIntObj( nkeys ) );
1100
if ( fitsGetWcsMatrixAlt(curFile, newptr, listObj, 0, NULL, '\0') > 0 ) {
1101
Tcl_SetResult(curFile->interp, "Failed to collect all the headers.", TCL_STATIC);
1105
if ( fitsGetWcsPairAlt(curFile, newptr, listObj, 0, 0, '\0') > 0 ) {
1106
Tcl_SetResult(curFile->interp, "Failed to collect all the headers.", TCL_STATIC);
1110
Tcl_SetObjResult(curFile->interp, listObj);
1116
} else if( !strcmp("header2str", argv[2]) ) {
1117
/* int ffhdr2str( fitsfile *fptr, I - FITS file pointer */
1118
/* int exclude_comm, I - if TRUE, exclude commentary keywords */
1119
/* char **exclist, I - list of excluded keyword names */
1120
/* int nexc, I - number of names in exclist */
1121
/* char **header, O - returned header string */
1122
/* int *nkeys, O - returned number of 80-char keywords */
1123
/* int *status) IO - error status */
1125
if ( ffhdr2str(curFile->fptr, 1, (char **)NULL, 0, &header, &nkeys, &status) > 0 ) {
1126
Tcl_SetResult(curFile->interp, "Failed to collect all the headers.", TCL_STATIC);
1130
Tcl_ListObjAppendElement( curFile->interp, listObj, Tcl_NewStringObj(header, -1));
1131
Tcl_ListObjAppendElement( curFile->interp, listObj, Tcl_NewIntObj( nkeys ) );
1132
Tcl_SetObjResult(curFile->interp, listObj);
1137
} else if( !strcmp("imgwcs", argv[2]) ) {
1141
if ( curFile->hduType != IMAGE_HDU ) {
1142
Tcl_SetResult(curFile->interp,
1143
"Current extension is not an image", TCL_STATIC);
1147
if( fitsGetWcsPair(curFile,0,0,'\0') != TCL_OK ) {
1151
} else if( !strcmp("colwcs", argv[2]) ) {
1158
if( curFile->hduType == IMAGE_HDU ) {
1159
Tcl_SetResult(curFile->interp,
1160
"Current extension is not a table", TCL_STATIC);
1164
Tcl_SetResult(curFile->interp,
1165
"get colwcs RAcol DECcol", TCL_STATIC);
1169
if( Tcl_GetInt(curFile->interp, argv[3], &ranum) != TCL_OK ) {
1170
Tcl_ResetResult(curFile->interp);
1171
if( fitsTransColList( curFile, argv[3],
1172
&numCols, colNums, colTypes, strSize)
1174
Tcl_SetResult(curFile->interp,
1175
"Unable to read RAcol", TCL_STATIC);
1178
if( numCols != 1 ) {
1179
Tcl_SetResult(curFile->interp,
1180
"Can only have 1 RAcol value", TCL_STATIC);
1186
if( Tcl_GetInt(curFile->interp, argv[4], &decnum) != TCL_OK ) {
1187
Tcl_ResetResult(curFile->interp);
1188
if( fitsTransColList( curFile, argv[4],
1189
&numCols, colNums, colTypes, strSize)
1191
Tcl_SetResult(curFile->interp,
1192
"Unable to read DecCol", TCL_STATIC);
1195
if( numCols != 1 ) {
1196
Tcl_SetResult(curFile->interp,
1197
"Can only have 1 DecCol value", TCL_STATIC);
1200
decnum = colNums[0];
1203
if( fitsTableGetWcsOld(curFile, ranum, decnum) != TCL_OK ) {
1207
} else if( !strcmp("image", argv[2]) ) {
1211
if( argc < 3 || argc > 5 ) {
1212
Tcl_SetResult(curFile->interp,
1213
"get image firstElem numElem", TCL_STATIC);
1217
if( curFile->hduType != IMAGE_HDU ) {
1218
Tcl_SetResult(curFile->interp,
1219
"Current extension is not a table", TCL_STATIC);
1224
fElem = atol( argv[3] );
1226
nElem = atol( argv[4] );
1233
i = curFile->CHDUInfo.image.naxes;
1235
nElem *= curFile->CHDUInfo.image.naxisn[i];
1238
if( imageBlockLoad_1D(curFile, fElem, nElem) != TCL_OK ) {
1242
} else if ( !strcmp("imageblock", argv[2]) ) {
1244
/* GET IMAGE in blocks */
1249
if( argc < 8 || argc > 10 ) {
1250
Tcl_SetResult(curFile->interp,
1251
"FitsHandle get imageblock arrayName firstRow "
1252
"numRows firstCol numCols ?2D image slice? ?cube slice?", TCL_STATIC);
1256
if( curFile->hduType != IMAGE_HDU ) {
1257
Tcl_SetResult(curFile->interp,
1258
"Current extension is not an image.", TCL_STATIC);
1263
slice = atol(argv[8]);
1266
cslice = atol(argv[9]);
1268
if( imageBlockLoad(curFile, argv[3], atoll(argv[4]), atoll(argv[5]),
1269
atoll(argv[6]), atoll(argv[7]), slice, cslice )
1271
return TCL_ERROR; /* Sets own error message */
1274
} else if( !strcmp("table",argv[2] ) ) {
1280
if ( curFile->hduType == IMAGE_HDU ) {
1281
Tcl_SetResult(curFile->interp,
1282
"Current extension is not a table", TCL_STATIC);
1286
if( curFile->CHDUInfo.table.loadStatus != 1 ) {
1287
Tcl_SetResult(curFile->interp,
1288
"Need to load the hdu first", TCL_STATIC);
1293
* Strip off the "-c" flag if present...
1299
while( idx < argc && argv[idx][0]=='-' ) {
1300
if( !strcmp(argv[idx],"-c") ) {
1302
} else if( !strcmp(argv[idx],"-noformat") ) {
1310
if( argc-idx > 2 ) {
1311
Tcl_SetResult(curFile->interp,
1312
"Wrong number of arguments, need "
1313
"'get table ?-c? ?-noformat? ?columns? ?rows?'",
1318
/* If no colList is given, or it is "*", use all the columns... */
1321
fitsTransColList( curFile, ( argc==idx ? "*" : argv[idx] ),
1322
&numCols, colNums, colTypes, strSize) )
1326
* Get the Row range parameter
1332
range = (int*) malloc(numRange*2*sizeof(int));
1334
range[1] = curFile->CHDUInfo.table.numRows;
1336
numRange =fitsParseRangeNum(argv[idx])+1;
1337
range = (int*) malloc(numRange*2*sizeof(int));
1338
if( fitsParseRange( argv[idx], &numRange, range, numRange,
1339
1, curFile->CHDUInfo.table.numRows, errMsg )
1341
Tcl_SetResult(curFile->interp,
1342
"Error parsing row range:\n", TCL_STATIC);
1343
Tcl_AppendResult(curFile->interp, errMsg, (char*)NULL);
1348
/* Now get the rows... */
1351
listArray = (Tcl_Obj**) ckalloc( numCols * sizeof(Tcl_Obj*) );
1352
for( k=0; k<numCols; k++ )
1353
listArray[k] = Tcl_NewListObj( 0, NULL );
1355
valArray = (Tcl_Obj**) ckalloc( numCols * sizeof(Tcl_Obj*) );
1356
listObj = Tcl_NewListObj( 0, NULL );
1359
for (i = 0; i < numRange; i++ ) {
1361
while( fRow <= range[i*2+1] ) {
1362
ntodo = range[i*2+1] - fRow + 1;
1363
if( ntodo>FITS_CHUNKSIZE ) ntodo = FITS_CHUNKSIZE;
1364
status = tableBlockLoad( curFile, "", 1, fRow, ntodo,
1365
-99, numCols, colNums, format );
1367
if( status != TCL_OK )
1371
resObj = Tcl_GetObjResult( curFile->interp );
1373
for( k = 0; k < numCols; k++) {
1374
Tcl_ListObjIndex( curFile->interp, resObj,
1376
Tcl_ListObjAppendList( curFile->interp,
1381
Tcl_ListObjGetElements( curFile->interp, resObj,
1383
for ( l = 0; l < ntodo; l++) {
1384
for( k = 0; k < numCols; k++) {
1385
Tcl_ListObjIndex( curFile->interp, listArray[k], l,
1388
Tcl_ListObjAppendElement( curFile->interp, listObj,
1389
Tcl_NewListObj(numCols, valArray) );
1398
ckfree( (char*) listArray );
1400
ckfree( (char*) valArray );
1406
Tcl_SetObjResult( curFile->interp,
1407
Tcl_NewListObj( numCols, listArray ) );
1409
Tcl_SetObjResult( curFile->interp, listObj );
1414
if( status ) return TCL_ERROR;
1416
} else if( !strcmp("vtable",argv[2]) ) {
1420
/* GET vector from the TABLE */
1422
if( curFile->hduType == IMAGE_HDU ) {
1423
Tcl_SetResult(curFile->interp,
1424
"Current extension is not a table", TCL_STATIC);
1428
if( curFile->CHDUInfo.table.loadStatus != 1 ){
1429
Tcl_SetResult(curFile->interp,
1430
"Need to load the hdu first", TCL_STATIC);
1436
if( idx<argc && !strcmp("-noformat",argv[idx]) ) {
1441
if( argc-idx < 2 ) {
1442
Tcl_SetResult(curFile->interp,
1443
"Wrong number of arguments, need "
1444
"'get vtable ?-noformat? column felem ?rowList?'",
1450
if( fitsTransColList( curFile, argv[idx++],
1451
&numCols, colNums, colTypes, strSize )
1454
if( numCols != 1 ) {
1455
Tcl_SetResult(curFile->interp,
1456
"Can only read one vector column of a table at a time",
1461
felem = atoi(argv[idx++]);
1464
* Get the Row range parameter
1469
range = (int*) malloc(numRange*2*sizeof(int));
1471
range[1] = curFile->CHDUInfo.table.numRows;
1473
numRange = fitsParseRangeNum(argv[idx])+1;
1474
range = (int*) malloc(numRange*2*sizeof(int));
1475
if( fitsParseRange( argv[idx++], &numRange, range, numRange,
1476
1, curFile->CHDUInfo.table.numRows, errMsg )
1478
Tcl_SetResult(curFile->interp,
1479
"Error parsing row range:\n", TCL_STATIC);
1480
Tcl_AppendResult(curFile->interp, errMsg, (char*)NULL);
1485
/* Now get the rows... */
1487
listObj = Tcl_NewListObj( 0, NULL );
1489
for (i = 0; i < numRange; i++ ) {
1491
while( fRow <= range[i*2+1] ) {
1492
ntodo = range[i*2+1] - fRow + 1;
1493
if( ntodo>FITS_CHUNKSIZE ) ntodo = FITS_CHUNKSIZE;
1495
if( tableBlockLoad( curFile, "", felem, fRow, ntodo,
1496
-99, numCols, colNums, format ) != TCL_OK )
1500
if( Tcl_ListObjIndex( curFile->interp,
1501
Tcl_GetObjResult( curFile->interp ), 0,
1505
if( Tcl_ListObjAppendList( curFile->interp, listObj, resObj )
1511
Tcl_SetObjResult( curFile->interp, listObj );
1515
Tcl_SetResult(curFile->interp,
1516
"ERROR: unrecognized command to get", TCL_STATIC);
1521
if (range) free(range);
1526
/******************************************************************
1528
******************************************************************/
1530
int fitsTcl_put( FitsFD *curFile, int argc, Tcl_Obj *const argv[] )
1532
static char *putKeyList = "put keyword ?-num n? card ?formatFlag?";
1533
static char *putHisList = "put history string";
1534
static char *putTabList =
1535
"put table colName firstElem rowSpan listOfData\n";
1537
static char *putImgList = "put image firstElem listOfData\n";
1539
static char *putIhdList =
1540
"put ihd ?-p? ?bitpix naxis naxesList? \n"
1541
" - -p primary extension \n";
1543
static char *putAhdList =
1544
"put ahd numRows numCols {colName} {colType} {colUnit} {tbCol}\n"
1545
" extname rowLength\n"
1546
" - colType: L(logical), X(bit), I(16 bit integer), "
1547
"J(32 bit integer)\n"
1548
" An(n Character), En(Single with n format), \n"
1549
" Dn(Double with n format), B(Unsigned) \n"
1550
" C(Complex), M(Double complex) ";
1552
static char *putBhdList =
1553
"put bhd numRows numCols {colName} {colType} {colUnit} extname \n"
1554
" - colType: nL(logical),nX(bit), nI(16 bit integer), "
1555
"nJ(32 bit integer)\n"
1556
" nA(Character), nE(Single), nD(Double), nB(Unsigned) \n"
1557
" nC(Complex), M(Double complex) ";
1559
int numCols,colNums[FITS_COLMAX],colTypes[FITS_COLMAX],strSize[FITS_COLMAX];
1560
int numRange, *range=NULL;
1561
char errMsg[256], *argStr, *cmd, **args;
1565
Tcl_SetResult(curFile->interp,"Available Commands:\n",TCL_STATIC);
1566
Tcl_AppendResult(curFile->interp, putKeyList,"\n", (char *)NULL);
1567
Tcl_AppendResult(curFile->interp, putTabList,"\n", (char *)NULL);
1568
Tcl_AppendResult(curFile->interp, putIhdList,"\n", (char *)NULL);
1569
Tcl_AppendResult(curFile->interp, putAhdList,"\n", (char *)NULL);
1570
Tcl_AppendResult(curFile->interp, putBhdList,"\n", (char *)NULL);
1574
cmd = Tcl_GetStringFromObj( argv[2], NULL );
1575
if( !strcmp( "keyword", cmd ) ) {
1579
int format, cardNum=0, recLoc=3;
1581
if( argc < 4 || argc > 7 ) {
1582
Tcl_SetResult(curFile->interp, putKeyList, TCL_STATIC);
1586
if( !strcmp(Tcl_GetStringFromObj(argv[3],NULL), "-num") ) {
1588
Tcl_SetResult(curFile->interp, putKeyList, TCL_STATIC);
1591
if( Tcl_GetIntFromObj(curFile->interp, argv[4], &cardNum) != TCL_OK ) {
1597
if( recLoc+1 < argc ) {
1598
if( Tcl_GetIntFromObj(curFile->interp, argv[recLoc+1], &format)
1606
if( fitsPutKwds(curFile, cardNum,
1607
Tcl_GetStringFromObj(argv[recLoc],NULL),
1613
} else if( !strcmp( "history", cmd ) ) {
1618
Tcl_SetResult(curFile->interp, putHisList, TCL_STATIC);
1622
if( fitsPutHisKwd(curFile, Tcl_GetStringFromObj(argv[3],NULL) )
1627
} else if( !strcmp ( "image", cmd ) ) {
1635
if( curFile->hduType != IMAGE_HDU ) {
1636
Tcl_SetResult(curFile->interp,
1637
"Current extension is not an image", TCL_STATIC);
1640
if( argc < 5 || argc > 6 ) {
1641
Tcl_SetResult(curFile->interp, putImgList, TCL_STATIC);
1645
if( Tcl_GetLongFromObj(curFile->interp, argv[3], &fElem) != TCL_OK ) {
1649
/* Skip to last argument... can get nElem directly from data list */
1651
if( Tcl_ListObjGetElements( curFile->interp, argv[argc-1],
1652
&nElem, &dataList ) != TCL_OK ) {
1656
if( varSaveToImage( curFile, fElem, (long)nElem, dataList ) != TCL_OK ) {
1660
} else if( !strcmp( "table", cmd ) ) {
1666
Tcl_Obj **dataElems;
1668
if ( curFile->hduType == IMAGE_HDU ) {
1669
Tcl_SetResult(curFile->interp,
1670
"Current extension is not a table", TCL_STATIC);
1675
Tcl_SetResult(curFile->interp, putTabList, TCL_STATIC);
1679
/* parse the column name */
1681
if( fitsTransColList(curFile, Tcl_GetStringFromObj(argv[3],NULL),
1682
&numCols,colNums,colTypes,strSize) != TCL_OK ) {
1685
if( numCols != 1 ) {
1686
Tcl_SetResult(curFile->interp,
1687
"Can only write one column at a time", TCL_STATIC);
1692
* Get the Row range parameter
1695
argStr = Tcl_GetStringFromObj( argv[5], NULL );
1696
numRange =fitsParseRangeNum(argStr)+1;
1697
range =(int*) malloc(numRange*2*sizeof(int));
1698
if( fitsParseRange(argStr,&numRange,range,numRange,
1699
1, curFile->CHDUInfo.table.numRows,errMsg)
1701
Tcl_SetResult(curFile->interp,
1702
"Error parsing row range:\n", TCL_STATIC);
1703
Tcl_AppendResult(curFile->interp, errMsg, (char*)NULL);
1706
if( numRange != 1 ) {
1707
Tcl_SetResult(curFile->interp,
1708
"Can only write one row range at a time", TCL_STATIC);
1712
if( Tcl_GetLongFromObj(curFile->interp,argv[4],&fElem) != TCL_OK ) {
1716
if ( Tcl_ListObjGetElements( curFile->interp, argv[6],
1717
&nElem, &dataElems ) != TCL_OK ) {
1721
if( varSaveToTable(curFile,
1725
range[1]-range[0]+1,
1727
dataElems ) != TCL_OK ) {
1731
} else if( !strcmp( "ihd", cmd ) ) {
1733
/* Write Image Header */
1736
if ( argc < 4 || argc > 7 ) {
1737
Tcl_SetResult(curFile->interp, putIhdList, TCL_STATIC);
1741
if( !strcmp( ARGV_STR(3), "-p" ) ) {
1747
args = (char **) ckalloc( argc * sizeof(char *) );
1748
for( i=0; i<argc; i++ ) {
1749
args[i] = ARGV_STR(i);
1752
if( fitsPutReqKwds(curFile, isPrimary, IMAGE_HDU,
1753
argc-3-isPrimary, args+3+isPrimary)
1755
ckfree( (char*)args );
1758
ckfree( (char*)args );
1760
} else if( !strcmp( "ahd", cmd ) ) {
1762
/* Write ASCII Table Header */
1764
char const *newArg[7];
1768
Tcl_SetResult(curFile->interp, putAhdList, TCL_STATIC);
1772
/* Strip out the numCols[4] parameter... use colNames length instead */
1774
for( j=0,i=3; i<11; i++ ) {
1776
newArg[j++] = ARGV_STR(i);
1779
if( fitsPutReqKwds(curFile, 0, ASCII_TBL, 7, (char **)newArg)
1784
} else if( !strcmp( "bhd", cmd ) ) {
1786
/* Write Binary Table Header */
1788
char const *newArg[5];
1792
Tcl_SetResult(curFile->interp, putBhdList, TCL_STATIC);
1796
/* Strip out the numCols[4] parameter... use colNames length instead */
1798
for( j=0,i=3; i<9; i++ ) {
1800
newArg[j++] = ARGV_STR(i);
1803
if( fitsPutReqKwds(curFile, 0, BINARY_TBL, 5, (char **)newArg)
1810
Tcl_SetResult(curFile->interp, "Unknown put function", TCL_STATIC);
1815
if (range) free(range);
1820
/******************************************************************
1822
******************************************************************/
1824
int fitsTcl_insert( FitsFD *curFile, int argc, char *const argv[] )
1826
static char *insertList[] = {
1827
"insert keyword index record ?formatflag?",
1828
"insert column index colName colForm",
1829
"insert row index numRows",
1830
"insert image ?-p? ?bitpix naxis naxesList? \n"
1831
" - -p primary extension, keywords optional if empty array",
1832
"insert table numRows {colNames} {colForms} ?{colUnits} extname?\n"
1833
" - colForm: nL(logical),nX(bit), nI(16 bit integer), "
1834
"nJ(32 bit integer)\n"
1835
" nA(Character), nE(Single), nD(Double), nB(Unsigned) \n"
1836
" nC(Complex), M(Double complex) \n"
1837
"insert table -ascii numRows {colNames} {colForms} ?{colUnits}\n"
1838
" {tbCols} extname rowWidth?\n"
1839
" - colForm: L(logical), X(bit), I(16 bit integer), "
1840
"J(32 bit integer)\n"
1841
" An(n Character), En(Single with n format), \n"
1842
" Dn(Double with n format), B(Unsigned) \n"
1843
" C(Complex), M(Double complex) " };
1845
int index, format, numRows, i;
1848
Tcl_AppendResult(curFile->interp,
1849
"Available commands:\n",
1850
insertList[0], "\n",
1851
insertList[1], "\n",
1852
insertList[2], "\n",
1853
insertList[3], "\n",
1854
insertList[4], "\n",
1859
if( !strcmp( "keyword", argv[2] ) ) {
1861
if( argc < 5 || argc > 6 ) {
1862
Tcl_SetResult(curFile->interp, insertList[0], TCL_STATIC);
1866
if( Tcl_GetInt(curFile->interp, argv[3], &index) != TCL_OK) {
1867
Tcl_SetResult(curFile->interp,
1868
"Failed to get integer index", TCL_STATIC);
1873
if ( Tcl_GetInt(curFile->interp, argv[5], &format) != TCL_OK) {
1874
Tcl_SetResult(curFile->interp,
1875
"Failed to get integer format flag", TCL_STATIC);
1882
if( fitsInsertKwds(curFile, index, argv[4], format) != TCL_OK ) {
1886
} else if( !strcmp( "column", argv[2] ) ) {
1889
Tcl_SetResult(curFile->interp, insertList[1], TCL_STATIC);
1893
if( Tcl_GetInt(curFile->interp, argv[3], &index) != TCL_OK) {
1894
Tcl_SetResult(curFile->interp,
1895
"Failed to get integer index", TCL_STATIC);
1899
if( addColToTable(curFile,index,argv[4],argv[5]) != TCL_OK ) {
1903
} else if( !strcmp( "row", argv[2] ) ) {
1906
Tcl_SetResult(curFile->interp, insertList[2], TCL_STATIC);
1910
if( Tcl_GetInt(curFile->interp, argv[3], &index) != TCL_OK) {
1911
Tcl_SetResult(curFile->interp,
1912
"Failed to get integer index", TCL_STATIC);
1916
if( Tcl_GetInt(curFile->interp, argv[4], &numRows) != TCL_OK) {
1917
Tcl_SetResult(curFile->interp,
1918
"Failed to get integer numRows", TCL_STATIC);
1921
if( addRowToTable(curFile,index-1,numRows) != TCL_OK ) {
1925
} else if( !strcmp( "image", argv[2] ) ) {
1927
/* Write Image Header */
1930
if ( argc < 4 || argc > 7 ) {
1931
Tcl_SetResult(curFile->interp, insertList[3], TCL_STATIC);
1936
* Strip off the "-p" flag if present...
1939
if( !strcmp(argv[3],"-p") ) {
1945
if( fitsPutReqKwds(curFile, isPrimary, IMAGE_HDU,
1946
argc-3-isPrimary, argv+3+isPrimary)
1951
} else if( !strcmp( "table", argv[2] ) ) {
1953
/* Write Table Header */
1957
if( argc>3 && !strcmp( "-ascii", argv[3] ) ) {
1959
tabType = ASCII_TBL;
1960
if( argc < 7 || argc > 11 ) {
1961
Tcl_SetResult(curFile->interp, insertList[4], TCL_STATIC);
1967
tabType = BINARY_TBL;
1968
if( argc < 6 || argc > 8 ) {
1969
Tcl_SetResult(curFile->interp, insertList[4], TCL_STATIC);
1975
if( fitsPutReqKwds(curFile, 0, tabType,
1976
argc-3-(tabType==ASCII_TBL?1:0),
1977
argv+3+(tabType==ASCII_TBL?1:0))
1984
Tcl_SetResult(curFile->interp, "No such insert command", TCL_STATIC);
1992
/******************************************************************
1994
******************************************************************/
1996
int fitsTcl_select( FitsFD *curFile, int argc, char *const argv[] )
1999
static char *selRowList =
2000
"select rows -expr expression firstrow nrow\n ";
2002
int numCols,colNums[FITS_COLMAX],colTypes[FITS_COLMAX],strSize[FITS_COLMAX];
2008
Tcl_Obj *valObj, *listObj;
2012
Tcl_AppendResult(curFile->interp, selRowList,(char *) NULL);
2017
if( !strcmp("rows", argv[2]) ) {
2020
Tcl_SetResult(curFile->interp, selRowList, TCL_STATIC);
2024
if( !strcmp("-expr", argv[3]) ) {
2025
if( Tcl_GetInt(curFile->interp, argv[5], &fRow) != TCL_OK ) {
2028
if( Tcl_GetInt(curFile->interp, argv[6], &nRows) != TCL_OK ) {
2031
row_status = (char*) malloc((nRows+1)*sizeof(char));
2032
listObj = Tcl_NewObj();
2034
if( fitsSelectRowsExpr(curFile, argv[4], fRow,nRows, &n_good_rows,row_status) == TCL_OK ) {
2035
/* for ( i=0 ; i< nRows; i++ ) {
2036
# if ( row_status[i] == 1 ) {
2037
# sprintf(result,"%d",i+fRow);
2038
# Tcl_AppendElement(curFile->interp,result);
2042
for (i=0; i < nRows; i++) {
2043
if ( row_status[i] == 1 ) {
2044
valObj = Tcl_NewLongObj( i+fRow );
2045
Tcl_ListObjAppendElement( curFile->interp, listObj, valObj);
2048
Tcl_SetObjResult( curFile->interp, listObj);
2053
if(row_status) free(row_status);
2057
Tcl_SetResult(curFile->interp, selRowList, TCL_STATIC);
2062
Tcl_SetResult(curFile->interp,
2063
"Unrecognized option to select", TCL_STATIC);
2069
if(row_status) free(row_status);
2075
/******************************************************************
2077
******************************************************************/
2079
int fitsTcl_delete( FitsFD *curFile, int argc, char *const argv[] )
2081
static char *delKeyList =
2082
"delete keyword KeyList\n"
2083
" (KeyList can be a mix of keyword names and keyword numbers\n";
2085
static char *delHduList =
2088
static char *delTabList =
2089
"delete cols colList\n ";
2091
static char *delRowList =
2092
"delete rows -expr expression\n "
2093
"delete rows -range rangelist\n "
2094
"delete rows firstRow numRows\n ";
2096
int numCols,colNums[FITS_COLMAX],colTypes[FITS_COLMAX],strSize[FITS_COLMAX];
2100
Tcl_AppendResult(curFile->interp, delKeyList, delHduList, delTabList,
2101
delRowList, (char *) NULL);
2105
if( !strcmp("keyword", argv[2]) ) {
2108
Tcl_SetResult(curFile->interp, delKeyList, TCL_STATIC);
2112
if( fitsDeleteKwds(curFile, argv[3] ) != TCL_OK ) {
2116
} else if( !strcmp("cols", argv[2]) ) {
2119
Tcl_SetResult(curFile->interp, delTabList, TCL_STATIC);
2122
if( fitsTransColList( curFile,argv[3],
2123
&numCols,colNums,colTypes,strSize) != TCL_OK )
2126
if( fitsDeleteCols(curFile, colNums, numCols) != TCL_OK ) {
2130
} else if( !strcmp("rows", argv[2]) ) {
2133
Tcl_SetResult(curFile->interp, delRowList, TCL_STATIC);
2137
if( !strcmp("-expr", argv[3]) ) {
2138
if( fitsDeleteRowsExpr(curFile, argv[4]) != TCL_OK ) {
2141
} else if (!strcmp("-range", argv[3]) ) {
2142
if( fitsDeleteRowsRange(curFile, argv[4]) != TCL_OK ) {
2147
if( Tcl_GetInt(curFile->interp, argv[3], &fRow) != TCL_OK ) {
2150
if( Tcl_GetInt(curFile->interp, argv[4], &nRows) != TCL_OK ) {
2153
if( fitsDeleteRows(curFile, fRow, nRows) != TCL_OK ) {
2158
} else if( !strcmp("chdu", argv[2]) ) {
2161
Tcl_SetResult(curFile->interp, delHduList, TCL_STATIC);
2164
if( fitsDeleteCHdu(curFile) != TCL_OK ) {
2170
Tcl_SetResult(curFile->interp,
2171
"Unrecognized option to delete", TCL_STATIC);
2180
/******************************************************************
2182
******************************************************************/
2184
int fitsTcl_load( FitsFD *curFile, int argc, char *const argv[] )
2186
static char *loadList = "\n"
2187
"load arrayRow colName ?defaultNull? ?firstElement? - Load a row\n"
2188
"load column colName ?defaultNull? ?firstElement? - Load a column\n"
2189
"load vtable colName - Load all elements of a vector column into memory\n"
2190
"load tblock arrayName colList firstRow numRows colIndex ?felem?\n"
2191
" - load a chunk of table and set up an array \"arrayName\"\n"
2192
" with indices of (colIndex-1,firstRow-1), etc \n"
2193
"load copyto filename taget\n"
2194
"load image ?slice? ?rotate? - Load a 2D slice of an image into memory\n"
2195
" (rotate: number of 90deg ccw rotations to perform)\n"
2196
"load irows firstRow lastRow ?slice? - load mean value of rows\n"
2197
"load icols firstCol lastCol ?slice? - load mean value of columns\n"
2198
"load iblock arrayName firstRow numRows fitsCol numCols ?slice?\n"
2199
" - load 2d image slice into an array or memory\n"
2200
" if arrayName is --, then a pointer is returned\n"
2201
"load expr expression ?defaultNull?\n"
2202
"load keyword - load the header of CHDU into a hash table \n"
2203
"load chdu - load the CHDU (useful if you move to the CHDU with -s,\n"
2204
" which does't load the HDUInfo) \n";
2206
int numCols,colNums[FITS_COLMAX],colTypes[FITS_COLMAX],strSize[FITS_COLMAX];
2210
fitsfile *infptr, *outfptr; /* FITS file pointers defined in fitsio.h */
2211
int status = 0, ii = 1, iteration = 0, single = 0, hdupos;
2212
int hdutype, bitpix, bytepix, naxis = 0, nkeys, datatype = 0, anynul;
2213
long naxes[9] = {1, 1, 1, 1, 1, 1, 1, 1, 1};
2214
long first, totpix = 0, npix;
2215
double *array, bscale = 1.0, bzero = 0.0, nulval = 0.;
2220
Tcl_SetResult(curFile->interp, loadList, TCL_STATIC);
2224
if( !strcmp("keyword", argv[2]) ) {
2226
/* Now LOAD the kwds hash table... */
2228
if( fitsLoadKwds(curFile) != TCL_OK ) {
2229
fitsCloseFile((ClientData) curFile);
2233
} else if( !strcmp("irows", argv[2]) ) {
2237
if( curFile->hduType != IMAGE_HDU ) {
2238
Tcl_SetResult(curFile->interp,
2239
"Current extension is not an image", TCL_STATIC);
2244
Tcl_SetResult(curFile->interp,
2245
"FitsHandle load irows firstRow lastRows ?slice?",
2253
slice = atol(argv[5]);
2256
if( imageRowsMeanToPtr(curFile,
2257
atol(argv[3]), /* first row */
2258
atol(argv[4]), /* last row*/
2259
slice ) != TCL_OK ) {
2260
Tcl_AppendResult(curFile->interp,
2261
"fitsTcl Error: cannot load irows", NULL);
2265
} else if( !strcmp("icols", argv[2]) ) {
2269
if( curFile->hduType != IMAGE_HDU ) {
2270
Tcl_SetResult(curFile->interp,
2271
"Current extension is not an image", TCL_STATIC);
2276
Tcl_SetResult(curFile->interp,
2277
"FitsHandle load icols firstCol lastCols ?slice?",
2285
slice = atol(argv[5]);
2288
if( imageColsMeanToPtr(curFile, atol(argv[3]),
2289
atol(argv[4]), slice) != TCL_OK ) {
2290
Tcl_AppendResult(curFile->interp,
2291
"\nfitsTcl Error: cannot load icols",
2296
} else if( !strcmp("iblock", argv[2]) ) {
2300
LONGLONG cslice = 1;
2302
if ( curFile->hduType != IMAGE_HDU ) {
2303
Tcl_SetResult(curFile->interp,
2304
"Current extension is not an image", TCL_STATIC);
2308
if( argc < 8 || argc > 10 ) {
2309
Tcl_SetResult(curFile->interp,
2310
"FitsHandle load iblock varName firstRow numRows "
2311
"firstCol numCols ?slice?", TCL_STATIC);
2316
slice = atoll(argv[8]);
2319
cslice = atoll(argv[9]);
2321
if( strcmp( argv[3], "--" ) )
2324
if( imageBlockLoad(curFile, varName, atoll(argv[4]),
2325
atoll(argv[5]), atoll(argv[6]),
2326
atoll(argv[7]), slice, cslice )
2331
} else if( !strcmp("tblock", argv[2]) ) {
2337
if ( curFile->hduType == IMAGE_HDU ) {
2338
Tcl_SetResult(curFile->interp,
2339
"Current extension is not a table", TCL_STATIC);
2343
if (argc < 8 || argc > 11) {
2344
Tcl_SetResult(curFile->interp,
2345
"Usage: load tblock ?-noformat? arrayName colList "
2346
"firstRow numRows firstCol ?felem?", TCL_STATIC);
2351
if( !strcmp("-noformat", argv[idx]) ) {
2357
/* parse column list */
2359
if( fitsTransColList( curFile,argv[idx++],
2360
&numCols,colNums,colTypes,strSize) != TCL_OK )
2363
/* get the firstRow and numRows */
2365
if( Tcl_GetInt(curFile->interp, argv[idx++], &fRow) != TCL_OK )
2367
if( Tcl_GetInt(curFile->interp, argv[idx++], &nRows) != TCL_OK )
2369
if( Tcl_GetInt(curFile->interp, argv[idx++], &fCol) != TCL_OK )
2372
/* Skip a possible obsolete value between fCol and last argument */
2374
if( argc>idx ) { /* Read felem from very last argument */
2375
if( Tcl_GetInt(curFile->interp, argv[argc-1], &felem) != TCL_OK )
2379
if( tableBlockLoad(curFile, argv[varIdx], felem, fRow, nRows,
2380
fCol, numCols, colNums, format) != TCL_OK )
2383
} else if( !strcmp("image", argv[2]) ) {
2388
if ( curFile->hduType != IMAGE_HDU ) {
2389
Tcl_SetResult(curFile->interp,
2390
"Current extension is not an image", TCL_STATIC);
2394
/* starting element, increment of naxisn[0] x naxisn[1]
2395
to get different frames of a 3d image */
2398
; /* default to the first frame to allow backward compatible */
2399
} else if( curFile->CHDUInfo.image.naxes <= 2 ) {
2403
slice = atol(argv[3]);
2405
Tcl_SetResult(curFile->interp,
2406
"fitsTcl Error: slice starts at 1", TCL_STATIC);
2410
if( slice > curFile->CHDUInfo.image.naxisn[2] ) {
2411
Tcl_SetResult(curFile->interp,
2412
"fitsTcl Error: slice exceeds the 3rd dim",
2419
rotate = atoi(argv[4]);
2420
if( rotate<0 || rotate>3 ) {
2421
Tcl_SetResult(curFile->interp,
2422
"fitsTcl Error: Illegal rotate value",
2430
if( imageGetToPtr(curFile, slice, rotate) != TCL_OK ) {
2436
} else if( !strcmp("copyto", argv[2]) ) {
2438
/* Open the input file and create output file */
2439
fits_open_file(&infptr, argv[3], READONLY, &status);
2440
fits_create_file(&outfptr, argv[4], &status);
2443
fits_report_error(stderr, status);
2447
fits_get_hdu_num(infptr, &hdupos); /* Get the current HDU position */
2449
/* Copy only a single HDU if a specific extension was given */
2450
if (hdupos != 1 || strchr(argv[3], '[')) single = 1;
2452
for (; !status; hdupos++) /* Main loop through each extension */
2455
fits_get_hdu_type(infptr, &hdutype, &status);
2457
if (hdutype == IMAGE_HDU) {
2459
/* get image dimensions and total number of pixels in image */
2460
for (ii = 0; ii < 9; ii++)
2463
fits_get_img_param(infptr, 9, &bitpix, &naxis, naxes, &status);
2465
totpix = naxes[0] * naxes[1] * naxes[2] * naxes[3] * naxes[4]
2466
* naxes[5] * naxes[6] * naxes[7] * naxes[8];
2469
if (hdutype != IMAGE_HDU || naxis == 0 || totpix == 0) {
2471
/* just copy tables and null images */
2472
fits_copy_hdu(infptr, outfptr, 0, &status);
2476
/* Explicitly create new image, to support compression */
2477
fits_create_img(outfptr, bitpix, naxis, naxes, &status);
2479
/* copy all the user keywords (not the structural keywords) */
2480
fits_get_hdrspace(infptr, &nkeys, NULL, &status);
2482
for (ii = 1; ii <= nkeys; ii++) {
2483
fits_read_record(infptr, ii, card, &status);
2484
if (fits_get_keyclass(card) > TYP_CMPRS_KEY)
2485
fits_write_record(outfptr, card, &status);
2505
datatype = TLONGLONG;
2509
bytepix = abs(bitpix) / 8;
2514
/* try to allocate memory for the entire image */
2515
/* use double type to force memory alignment */
2516
array = (double *) calloc(npix, bytepix);
2518
/* if allocation failed, divide size by 2 and try again */
2519
while (!array && iteration < 10) {
2522
array = (double *) calloc(npix, bytepix);
2526
fprintf(stdout,"Memory allocation error\n");
2530
/* turn off any scaling so that we copy the raw pixel values */
2531
fits_set_bscale(infptr, bscale, bzero, &status);
2532
fits_set_bscale(outfptr, bscale, bzero, &status);
2534
while (totpix > 0 && !status)
2536
/* read all or part of image then write it back to the output file */
2537
fits_read_img(infptr, datatype, first, npix,
2538
&nulval, array, &anynul, &status);
2540
fits_write_img(outfptr, datatype, first, npix, array, &status);
2541
totpix = totpix - npix;
2542
first = first + npix;
2547
if (single) break; /* quit if only copying a single HDU */
2548
fits_movrel_hdu(infptr, 1, NULL, &status); /* try to move to next HDU */
2551
if (status == END_OF_FILE) status = 0; /* Reset after normal error */
2553
fits_close_file(outfptr, &status);
2554
fits_close_file(infptr, &status);
2556
} else if( !strcmp("arrayRow", argv[2]) ) {
2558
char *nullPtr = "NULL";
2562
if( curFile->hduType == IMAGE_HDU ) {
2563
Tcl_SetResult(curFile->interp,
2564
"Current extension is not a table", TCL_STATIC);
2568
if( argc < 4 || argc > 8 ) {
2569
Tcl_SetResult(curFile->interp,
2570
"fitsObj load arrayRow colName rowNumber numElement ?nulValue? ?firstelem?",
2575
if( fitsTransColList( curFile, argv[3],
2576
&numCols, colNums, colTypes, strSize ) != TCL_OK )
2579
if( numCols != 1 ) {
2580
Tcl_SetResult(curFile->interp,
2581
"Can only load one column at a time", TCL_STATIC);
2585
rowNum = atol(argv[4]);
2586
nelem = atol(argv[5]);
2592
felem = atol(argv[7]);
2594
if( tableRowGetToPtr(curFile, rowNum, colNums[0], nelem, nullPtr, felem) ) {
2598
} else if( !strcmp("column", argv[2]) ) {
2600
char *nullPtr = "NULL";
2602
if( curFile->hduType == IMAGE_HDU ) {
2603
Tcl_SetResult(curFile->interp,
2604
"Current extension is not a table", TCL_STATIC);
2608
if( argc < 4 || argc > 6 ) {
2609
Tcl_SetResult(curFile->interp,
2610
"load column colName ?nulValue? ?firstelem?",
2615
if( fitsTransColList( curFile, argv[3],
2616
&numCols, colNums, colTypes, strSize ) != TCL_OK )
2619
if( numCols != 1 ) {
2620
Tcl_SetResult(curFile->interp,
2621
"Can only load one column at a time", TCL_STATIC);
2629
felem = atol(argv[5]);
2631
if( tableGetToPtr(curFile, colNums[0], nullPtr, felem) ) {
2635
} else if( !strcmp("vtable", argv[2]) ) {
2637
char *nullPtr = "NULL";
2639
if ( curFile->hduType == IMAGE_HDU ) {
2640
Tcl_SetResult(curFile->interp,
2641
"Current extension is not a table", TCL_STATIC);
2645
if( argc < 4 || argc > 5 ) {
2646
/* For backwards compatibility, allow for one extra parameter */
2647
/* ... formerly the vector size of column */
2648
/* PDW 12/06/99: Sacrifice backwards compat for adding defNull*/
2649
Tcl_SetResult(curFile->interp,
2650
"load vtable colName ?nulValue?", TCL_STATIC);
2654
if( fitsTransColList( curFile,argv[3],
2655
&numCols,colNums,colTypes,strSize) != TCL_OK )
2657
if( numCols != 1 ) {
2658
Tcl_SetResult( curFile->interp,
2659
"Can only load one column at a time", TCL_STATIC );
2666
if( vtableGetToPtr(curFile, colNums[0], nullPtr) ) {
2670
} else if( !strcmp("expr", argv[2]) ) {
2672
char *nullPtr = "NULL", errMsg[256];
2673
int numRange, *range=NULL;
2676
if( curFile->hduType == IMAGE_HDU ) {
2677
Tcl_SetResult(curFile->interp,
2678
"Current extension is not a table", TCL_STATIC);
2682
if( !strcmp("-rows", argv[3]) && argc>4 ) {
2683
numRange = fitsParseRangeNum(argv[4])+1;
2684
range = (int*) malloc(numRange*2*sizeof(int));
2685
if( fitsParseRange(argv[4],&numRange,range,numRange,
2686
1, curFile->CHDUInfo.table.numRows,errMsg)
2688
Tcl_SetResult(curFile->interp,
2689
"Error parsing row range:\n", TCL_STATIC);
2690
Tcl_AppendResult(curFile->interp, errMsg, (char*)NULL);
2696
range = (int*) malloc(numRange*2*sizeof(int));
2698
range[1] = curFile->CHDUInfo.table.numRows;
2701
if( argc < 4+argOff || argc-argOff > 5+argOff ) {
2702
Tcl_SetResult(curFile->interp,
2703
"Usage: load expr ?-rows range? exprStr ?nullVal?",
2708
if( argc > 4+argOff )
2709
nullPtr = argv[4+argOff];
2711
if( exprGetToPtr( curFile, argv[3+argOff], nullPtr, numRange, range ) ) {
2715
} else if( !strcmp("all", argv[2]) || !strcmp("chdu", argv[2]) ) {
2717
/* load the current hdu */
2719
if( fitsUpdateCHDU(curFile, curFile->hduType) != TCL_OK ) {
2720
Tcl_SetResult(curFile->interp,
2721
"fitsTcl Error: Cannot update current HDU",
2726
if( fitsLoadHDU(curFile) != TCL_OK ) {
2732
Tcl_SetResult(curFile->interp,
2733
"Error in fitsTcl: unknown load function", TCL_STATIC);
2742
/******************************************************************
2744
******************************************************************/
2746
int fitsTcl_free( FitsFD *curFile, int argc, Tcl_Obj *const argv[] )
2754
Tcl_SetResult(curFile->interp,
2761
Tcl_SetResult(curFile->interp, "Too many arguments to free",
2766
if( Tcl_ListObjGetElements(curFile->interp, argv[argc-1], &nAdd, &addList)
2768
Tcl_SetResult(curFile->interp,
2769
"Cannot parse the address list", TCL_STATIC);
2775
addStr = Tcl_GetStringFromObj( addList[nAdd], NULL );
2776
sscanf(addStr,PTRFORMAT,&databuff);
2777
if ( databuff == NULL) {
2778
Tcl_SetResult(curFile->interp,
2779
"Error interpretting pointer address", TCL_STATIC);
2782
ckfree( (char *) databuff);
2789
/******************************************************************
2791
******************************************************************/
2793
int fitsTcl_flush( FitsFD *curFile, int argc, Tcl_Obj *const argv[] )
2798
ffflsh(curFile->fptr, 0, &status);
2799
} else if( argc == 3 ) {
2801
opt = Tcl_GetStringFromObj( argv[2], NULL );
2802
if( !strcmp(opt, "clear") ) {
2803
ffflsh(curFile->fptr, 1, &status);
2805
Tcl_SetResult(curFile->interp, "fitsFile flush ?clear?", TCL_STATIC);
2809
Tcl_SetResult(curFile->interp, "fitsFile flush ?clear?", TCL_STATIC);
2814
Tcl_SetResult(curFile->interp,
2815
"fitsTcl Error: cannot flush file\n", TCL_STATIC);
2816
dumpFitsErrStack(curFile->interp, status);
2824
/******************************************************************
2826
******************************************************************/
2828
int fitsTcl_copy( FitsFD *curFile, int argc, Tcl_Obj *const argv[] )
2830
static char *copyList = "\n"
2833
Tcl_SetResult(curFile->interp, copyList, TCL_STATIC);
2837
if( fitsCopyCHduToFile(curFile, Tcl_GetStringFromObj( argv[2], NULL ) )
2846
/******************************************************************
2848
******************************************************************/
2850
int fitsTcl_sascii( FitsFD *curFile, int argc, char *const argv[] )
2852
static char *sasciiList =
2853
"sascii table filename fileMode firstRow numRows colList widthList\n"
2854
" ifFixedFormat ifCSV ifPrintRow sepString\n"
2855
"sascii image filename fileMode firstRow numRows firstCol\n"
2856
" numCols cellSize ifCSV ifPrintRow sepString ?slice?\n";
2858
int numCols,colNums[FITS_COLMAX],colTypes[FITS_COLMAX],strSize[FITS_COLMAX];
2860
int fCol, nCols, nWdths;
2861
int cellSize, i, baseColNum, ifVariableVec;
2862
int ifCSV, ifPrintRow, ifFixedFormat;
2869
Tcl_SetResult(curFile->interp, sasciiList, TCL_STATIC);
2873
if( !strcmp("table", argv[2]) ){
2875
if( argc < 13 || argc > 14 ) {
2876
Tcl_SetResult(curFile->interp,
2877
"Wrong # of args to 'sascii table'", TCL_STATIC);
2881
if( Tcl_GetInt(curFile->interp, argv[5], &fRow) != TCL_OK ) {
2882
Tcl_SetResult(curFile->interp, "Cannot get first row", TCL_STATIC);
2885
if( Tcl_GetInt(curFile->interp, argv[6], &nRows) != TCL_OK ) {
2886
Tcl_SetResult(curFile->interp, "Cannot get number of rows", TCL_STATIC);
2890
if( fitsTransColList( curFile,argv[7],
2891
&numCols,colNums,colTypes,strSize) != TCL_OK ) {
2892
Tcl_SetResult(curFile->interp, "Cannot parse the column list", TCL_STATIC);
2896
if( Tcl_SplitList(curFile->interp, argv[8], &nWdths, &listWid)
2898
Tcl_SetResult(curFile->interp, "Cannot parse the width list", TCL_STATIC);
2899
ckfree( (char*)listWid );
2903
if( nWdths != numCols ) {
2904
Tcl_SetResult(curFile->interp, "Cell width array and Column list have different sizes", TCL_STATIC);
2905
ckfree( (char*)listWid );
2909
for( i=0; i< numCols; i++ ) {
2910
if( Tcl_GetInt(curFile->interp, listWid[i], strSize+i) != TCL_OK ) {
2911
Tcl_SetResult(curFile->interp, "Unable to parse the width list", TCL_STATIC);
2912
ckfree( (char*)listWid );
2916
ckfree( (char*)listWid );
2918
if( Tcl_GetInt(curFile->interp, argv[9], &ifFixedFormat) != TCL_OK ) {
2919
Tcl_SetResult(curFile->interp, "Cannot get ifFixedFormat", TCL_STATIC);
2923
if( Tcl_GetInt(curFile->interp, argv[10], &ifCSV) != TCL_OK ) {
2924
Tcl_SetResult(curFile->interp, "Cannot get ifCSV", TCL_STATIC);
2928
if( Tcl_GetInt(curFile->interp, argv[11], &ifPrintRow) != TCL_OK ) {
2929
Tcl_SetResult(curFile->interp, "Cannot get ifPrintRow", TCL_STATIC);
2933
if( saveTableToAscii( curFile, argv[3], argv[4], 1, fRow, nRows,
2934
numCols, colTypes, colNums, strSize,
2935
ifFixedFormat, ifCSV, ifPrintRow, argv[12]) )
2938
} else if( !strcmp("image", argv[2]) ) {
2942
if( argc < 13 || argc > 14 ) {
2943
Tcl_SetResult(curFile->interp,
2944
"Wrong # of args to 'sascii image'", TCL_STATIC);
2949
slice = atol(argv[13]);
2951
if( Tcl_GetInt(curFile->interp, argv[5], &fRow) != TCL_OK ) {
2952
Tcl_SetResult(curFile->interp,
2953
"Cannot get first row", TCL_STATIC);
2956
if( Tcl_GetInt(curFile->interp, argv[6], &nRows) != TCL_OK ) {
2957
Tcl_SetResult(curFile->interp,
2958
"Cannot get number of rows", TCL_STATIC);
2961
if( Tcl_GetInt(curFile->interp, argv[7], &fCol) != TCL_OK ) {
2962
Tcl_SetResult(curFile->interp,
2963
"Cannot get first column", TCL_STATIC);
2966
if( Tcl_GetInt(curFile->interp, argv[8], &nCols) != TCL_OK ) {
2967
Tcl_SetResult(curFile->interp,
2968
"Cannot get number of columns", TCL_STATIC);
2971
if( Tcl_GetInt(curFile->interp, argv[9], &cellSize) != TCL_OK ) {
2972
Tcl_SetResult(curFile->interp,
2973
"Cannot get cellSize", TCL_STATIC);
2977
if( Tcl_GetInt(curFile->interp, argv[10], &ifCSV) != TCL_OK ) {
2978
Tcl_SetResult(curFile->interp,
2979
"Cannot get ifCSV", TCL_STATIC);
2983
if( Tcl_GetInt(curFile->interp, argv[11], &ifPrintRow) != TCL_OK ) {
2984
Tcl_SetResult(curFile->interp,
2985
"Cannot get ifPrintRow", TCL_STATIC);
2990
do error checking later
2991
sepString = argv[12];
2994
if( saveImageToAscii( curFile, argv[3], argv[4], fRow, nRows,
2995
fCol, nCols, cellSize,
2996
ifCSV, ifPrintRow, argv[12], slice ) )
2999
} else if( !strcmp("vector", argv[2]) ) {
3001
ifVariableVec = atol(argv[13]);
3003
if( Tcl_GetInt(curFile->interp, argv[5], &fRow) != TCL_OK ) {
3004
Tcl_SetResult(curFile->interp,
3005
"Cannot get first row", TCL_STATIC);
3008
if( Tcl_GetInt(curFile->interp, argv[6], &nRows) != TCL_OK ) {
3009
Tcl_SetResult(curFile->interp,
3010
"Cannot get number of rows", TCL_STATIC);
3013
if( Tcl_GetInt(curFile->interp, argv[7], &fCol) != TCL_OK ) {
3014
Tcl_SetResult(curFile->interp,
3015
"Cannot get first column", TCL_STATIC);
3018
if( Tcl_GetInt(curFile->interp, argv[8], &nCols) != TCL_OK ) {
3019
Tcl_SetResult(curFile->interp,
3020
"Cannot get number of columns", TCL_STATIC);
3024
if( fitsTransColList( curFile,argv[9],
3025
&numCols,colNums,colTypes,strSize) != TCL_OK ) {
3026
Tcl_SetResult(curFile->interp, "Cannot parse the column list", TCL_STATIC);
3031
baseColNum = colNums[0];
3033
if( Tcl_GetInt(curFile->interp, argv[10], &ifCSV) != TCL_OK ) {
3034
Tcl_SetResult(curFile->interp,
3035
"Cannot get ifCSV", TCL_STATIC);
3039
if( Tcl_GetInt(curFile->interp, argv[11], &ifPrintRow) != TCL_OK ) {
3040
Tcl_SetResult(curFile->interp,
3041
"Cannot get ifPrintRow", TCL_STATIC);
3046
do error checking later
3047
sepString = argv[12];
3050
if( saveVectorTableToAscii( curFile, argv[3], argv[4], fRow, nRows,
3051
fCol, nCols, baseColNum,
3052
ifCSV, ifPrintRow, argv[12], ifVariableVec ) )
3056
Tcl_SetResult(curFile->interp,
3057
"Unknown sascii command", TCL_STATIC);
3066
/******************************************************************
3068
******************************************************************/
3070
int fitsTcl_sort( FitsFD *curFile, int argc, char *const argv[] )
3072
static char *sortList =
3073
"sort ?-merge? colNameList ?isAscendFlagList? \n";
3075
int numCols,colNums[FITS_COLMAX],colTypes[FITS_COLMAX],strSize[FITS_COLMAX];
3078
char *const *argPtr;
3084
Tcl_SetResult(curFile->interp, sortList, TCL_STATIC);
3088
if( curFile->hduType == IMAGE_HDU ) {
3089
Tcl_SetResult(curFile->interp, "Cannot sort an image", TCL_STATIC);
3096
if( !strcmp(argPtr[0], "-merge") ) {
3102
if( fitsTransColList( curFile,argPtr[0],
3103
&numCols,colNums,colTypes,strSize) != TCL_OK ) {
3107
isAscend = (int *) ckalloc(numCols*sizeof(int));
3109
/* if no isAscend specified, set as default ascend */
3113
for (i=0; i < numCols; i++)
3118
if( Tcl_SplitList(curFile->interp, argPtr[1],
3119
&listNum, &listPtr) != TCL_OK ) {
3120
ckfree((char *) isAscend);
3123
if( listNum != numCols ) {
3124
Tcl_SetResult(curFile->interp,
3125
"fitsTcl Error: number of flags and columns don't match",
3127
ckfree((char *) isAscend);
3128
ckfree((char *) listPtr);
3131
for (i=0; i< listNum; i++) {
3132
if( Tcl_GetInt(curFile->interp, listPtr[i], &isAscend[i]) != TCL_OK ) {
3133
ckfree((char*) isAscend);
3134
ckfree((char*) listPtr);
3135
Tcl_SetResult(curFile->interp,
3136
"fitsTcl Error: cannot parse sort flag", TCL_STATIC);
3140
ckfree((char *) listPtr);
3144
if( fitsSortTable(curFile, numCols, colNums,
3145
strSize, isAscend, isMerge) != TCL_OK ) {
3146
ckfree ((char *) isAscend);
3150
ckfree ((char *) isAscend);
3155
/******************************************************************
3157
******************************************************************/
3159
int fitsTcl_add( FitsFD *curFile, int argc, char *const argv[] )
3161
static char *addColList =
3162
"add column colName colForm ?expr?\n"
3163
"add column colName colForm ?expr? ?rowrange?\n"
3165
" ASCII Table: A15, I10, E12.5, D20.10, F14.6 ... \n"
3166
" BINARY Table: 15A, 1I, 1J, 1E, 1D, 1L, 1X, 1B, 1C, 1M\n";
3167
static char *addRowList = "add row numRows\n";
3169
int numCols,colNums[FITS_COLMAX],colTypes[FITS_COLMAX],strSize[FITS_COLMAX];
3170
int numRange,rangeBlock, *range=NULL;
3174
/* range = (int*) malloc(FITS_MAXRANGE*2*sizeof(int)); */
3176
Tcl_AppendResult(curFile->interp, addColList, addRowList, (char*)NULL);
3180
if( !strcmp(argv[2], "column") ) {
3184
if( addColToTable(curFile, FITS_COLMAX, argv[3], argv[4])
3189
} else if( argc >= 6 ) {
3194
strToUpper(argv[3], &tmpColName);
3195
if( fitsTransColList(curFile,tmpColName,
3196
&numCols,colNums,colTypes,strSize) != TCL_OK ) {
3198
/* column name doesn't exist, add a new column*/
3201
} else if( numCols == 1 ) {
3204
Tcl_SetResult(curFile->interp,
3205
"Can only add one column at a time", TCL_STATIC);
3206
ckfree((char *) tmpColName);
3209
ckfree((char *) tmpColName);
3211
/* Feb 2004, Ziqin Pan add */
3213
numRange = fitsParseRangeNum(argv[6])+1;
3214
range = (int*) malloc(numRange*2*sizeof(int));
3215
if ( fitsParseRange(argv[6],&numRange,range,numRange, 1, curFile->CHDUInfo.table.numRows,errMsg)
3217
Tcl_SetResult(curFile->interp,
3218
"Error parsing row range:\n", TCL_STATIC);
3219
Tcl_AppendResult(curFile->interp, errMsg, (char*)NULL);
3222
if ( fitsCalculaterngColumn(curFile, argv[3], ( strcmp(argv[4],"default") ? argv[4] : NULL ),
3223
argv[5],numRange,range) != TCL_OK ) {
3227
if ( fitsCalculateColumn(curFile, argv[3], ( strcmp(argv[4],"default") ? argv[4] : NULL ),
3228
argv[5]) != TCL_OK ) {
3233
sprintf(result,"%d",isNew);
3234
Tcl_SetResult(curFile->interp, result, TCL_VOLATILE);
3238
Tcl_SetResult(curFile->interp, addColList, TCL_STATIC);
3243
} else if( !strcmp(argv[2], "row") ) {
3248
Tcl_SetResult(curFile->interp, addRowList, TCL_STATIC);
3251
if( Tcl_GetInt(curFile->interp, argv[3], &numRows) != TCL_OK) {
3252
Tcl_SetResult(curFile->interp,
3253
"Failed to get numRows parameter", TCL_STATIC);
3256
if( addRowToTable(curFile, curFile->CHDUInfo.table.numRows,
3257
numRows) != TCL_OK ) {
3263
Tcl_SetResult(curFile->interp, "Unknown add command", TCL_STATIC);
3268
if (range) free(range);
3273
/******************************************************************
3275
******************************************************************/
3277
int fitsTcl_append( FitsFD *curFile, int argc, Tcl_Obj *const argv[] )
3279
static char *appendList = "\n"
3280
"append filename \n"
3281
" -- append the chdu to another file\n";
3284
Tcl_SetResult(curFile->interp, appendList, TCL_STATIC);
3288
if( fitsAppendCHduToFile(curFile, Tcl_GetStringFromObj( argv[2], NULL ) )
3297
/******************************************************************
3299
******************************************************************/
3301
int fitsTcl_histo( FitsFD *curFile, int argc, Tcl_Obj *const argv[] )
3303
static char *histoList = "\n"
3304
"histogram ?-weight w? ?-rows rowSpan? filename {col min max bin} ... \n";
3306
int i, j, argNum, nRows;
3308
int numRange, *range=NULL;
3312
/* Args to ffhist */
3315
int imagetype = TINT;
3317
char colname[4][FLEN_VALUE];
3320
double binsizein[4];
3321
char minname[4][FLEN_VALUE];
3322
char maxname[4][FLEN_VALUE];
3323
char binname[4][FLEN_VALUE];
3325
char wtcol[FLEN_VALUE];
3327
char *selectrow=NULL;
3331
Tcl_SetResult(curFile->interp, histoList, TCL_STATIC);
3335
if( curFile->hduType == IMAGE_HDU ) {
3336
Tcl_SetResult(curFile->interp, "Cannot histogram an image", TCL_STATIC);
3340
/* Zero out all the parameters */
3342
for( i=0; i<4; i++ ) {
3343
colname[i][0] = '\0';
3344
minname[i][0] = '\0'; minin[i] = DOUBLENULLVALUE;
3345
maxname[i][0] = '\0'; maxin[i] = DOUBLENULLVALUE;
3346
binname[i][0] = '\0'; binsizein[i] = DOUBLENULLVALUE;
3351
/* Search for histogram options */
3354
nRows = curFile->CHDUInfo.table.numRows;
3356
do { /* argc guaranteed to be at least 3 */
3358
opt = Tcl_GetStringFromObj( argv[argNum++], NULL );
3359
if( opt[0]!='-' ) break;
3361
if( !strcmp(opt,"-weight") ) {
3363
if( argNum == argc ) {
3364
Tcl_SetResult(curFile->interp, histoList, TCL_STATIC);
3365
if( selectrow ) ckfree( (char*)selectrow );
3368
if( Tcl_GetDoubleFromObj( curFile->interp, argv[argNum], &weightin )
3370
strcpy( wtcol, Tcl_GetStringFromObj( argv[argNum], NULL ) );
3375
} else if( !strcmp(opt,"-inverse") ) {
3379
} else if( !strcmp(opt,"-rows") ) {
3381
if( argNum == argc ) {
3382
Tcl_SetResult(curFile->interp, histoList, TCL_STATIC);
3383
if( selectrow ) ckfree( (char*)selectrow );
3386
opt = Tcl_GetStringFromObj( argv[argNum++], NULL );
3387
numRange = fitsParseRangeNum(opt)+1;
3388
range = (int*) malloc(numRange*2*sizeof(int));
3389
if( fitsParseRange( opt, &numRange, range, numRange,
3392
Tcl_SetResult(curFile->interp,
3393
"Error parsing row range:\n", TCL_STATIC);
3394
Tcl_AppendResult(curFile->interp, errMsg, (char*)NULL);
3395
if( selectrow ) ckfree( (char*)selectrow );
3398
if( numRange>1 || range[0]!=1 || range[1]!=nRows ) {
3399
if( selectrow==NULL ) {
3400
selectrow = (char *)ckalloc( nRows * sizeof(char) );
3402
Tcl_SetResult( curFile->interp,
3403
"Unable to allocate row-selection array",
3407
for( i=0; i<nRows; i++ ) selectrow[i] = 0;
3409
for( i=0; i<numRange; i++ ) {
3410
for( j=range[i*2]; j<=range[i*2+1]; j++ ) {
3420
if( argNum >= argc ) {
3421
/* Need at least a filename parameter */
3422
Tcl_SetResult( curFile->interp, histoList, TCL_STATIC );
3423
if( selectrow ) ckfree( (char*)selectrow );
3427
} while( 1 ); /* Exit by one of breaks... found non option */
3429
/* opt should be pointing to the file name */
3433
naxis = argc - argNum;
3435
if( selectrow ) ckfree( (char*)selectrow );
3436
Tcl_SetResult( curFile->interp, "Missing binning arguments",
3441
if( selectrow ) ckfree( (char*)selectrow );
3442
Tcl_SetResult( curFile->interp, "Histograms are limited to 4 dimensions",
3447
/* Parse each of the binning lists */
3449
for( i=0; i<naxis; i++, argNum++ ) {
3451
if( Tcl_ListObjGetElements(curFile->interp, argv[argNum], &j, &binList)
3453
Tcl_SetResult(curFile->interp,
3454
"Cannot parse the column binning parameters",
3459
if( selectrow ) ckfree( (char*)selectrow );
3460
Tcl_SetResult( curFile->interp,
3461
"Binning list should be {colName min max binsize}",
3466
/* Get column name */
3467
opt = Tcl_GetStringFromObj( binList[0], &j );
3468
if( j<FLEN_VALUE ) {
3469
strcpy( colname[i], opt );
3472
strncpy( colname[i], opt, j );
3473
colname[i][j] = '\0';
3476
/* Get min parameter ... can be number, "-", or keyword name */
3477
if( Tcl_GetDoubleFromObj( curFile->interp, binList[1], minin+i )
3479
opt = Tcl_GetStringFromObj( binList[1], &j );
3480
if( strcmp(opt,"-") ) {
3481
/* Use supplied keyword name */
3482
if( j<FLEN_VALUE ) {
3483
strcpy( minname[i], opt );
3486
strncpy( minname[i], opt, j );
3487
minname[i][j] = '\0';
3492
/* Get max parameter ... can be number, "-", or keyword name */
3493
if( Tcl_GetDoubleFromObj( curFile->interp, binList[2], maxin+i )
3495
opt = Tcl_GetStringFromObj( binList[2], &j );
3496
if( strcmp(opt,"-") ) {
3497
/* Use supplied keyword name */
3498
if( j<FLEN_VALUE ) {
3499
strcpy( maxname[i], opt );
3502
strncpy( maxname[i], opt, j );
3503
maxname[i][j] = '\0';
3508
/* Get bin parameter ... can be number, "-", or keyword name */
3509
if( Tcl_GetDoubleFromObj( curFile->interp, binList[3], binsizein+i )
3511
opt = Tcl_GetStringFromObj( binList[3], &j );
3512
if( strcmp(opt,"-") ) {
3513
/* Use supplied keyword name */
3514
if( j<FLEN_VALUE ) {
3515
strcpy( binname[i], opt );
3518
strncpy( binname[i], opt, j );
3519
binname[i][j] = '\0';
3526
ffreopen( curFile->fptr, &fptr, &status );
3527
ffmahd( fptr, curFile->chdu, &j, &status );
3544
ffclos( fptr, &status );
3546
if (range) free(range);
3548
dumpFitsErrStack(curFile->interp, status);
3552
Tcl_ResetResult(curFile->interp);
3557
/******************************************************************
3559
******************************************************************/
3561
int fitsTcl_create( FitsFD *curFile, int argc, Tcl_Obj *const argv[] )
3563
static char *createList= "\n"
3564
"create 2dhisto filename {colList} {xmin xmax xbin} {ymin ymax ybin} ?rows?\n"
3565
" 1dhisto filename {colList} {xmin xmax xbin} ?row?\n"
3566
" (DEPRECATED) Use 'objName histogram' command instead\n";
3568
Tcl_Obj *newCmd[10];
3569
int newArgc, nelem, naxes, i;
3573
Tcl_SetResult(curFile->interp, createList, TCL_STATIC);
3577
opt = Tcl_GetStringFromObj( argv[2], NULL );
3578
if( !strcmp("dhisto", opt+1) ) {
3582
if( argc < 5 + naxes ) {
3583
Tcl_SetResult(curFile->interp, "Wrong # of args to 'create ndhisto'",
3589
newCmd[newArgc++] = argv[0];
3590
newCmd[newArgc++] = Tcl_NewStringObj("histogram",-1);
3592
/* Look for a row span */
3593
if ( argc > 5 + naxes) {
3594
newCmd[newArgc++] = Tcl_NewStringObj("-rows",-1);
3595
newCmd[newArgc++] = argv[argc-1];
3598
/* Look for a weight argument */
3599
Tcl_ListObjLength( curFile->interp, argv[4], &nelem );
3600
if( nelem<naxes || nelem>naxes+1 ) {
3601
Tcl_SetResult(curFile->interp, "Need 2-3 columns to produce histogram",
3605
if( nelem==naxes+1 ) {
3606
newCmd[newArgc++] = Tcl_NewStringObj("-weight",-1);
3607
Tcl_ListObjIndex( curFile->interp, argv[4], naxes, newCmd+newArgc );
3611
/* Grab filename argument */
3612
newCmd[newArgc++] = argv[3];
3614
/* Build axes bin parameter */
3615
for( i=0; i<naxes; i++ ) {
3616
Tcl_ListObjLength( curFile->interp, argv[5+i], &nelem );
3618
Tcl_SetResult(curFile->interp,
3619
"Incorrect axis binning parameters",
3623
Tcl_ListObjIndex( curFile->interp, argv[4], i, newCmd+newArgc );
3624
newCmd[newArgc] = Tcl_NewListObj(1,newCmd+newArgc);
3625
Tcl_ListObjAppendList( curFile->interp, newCmd[newArgc], argv[5+i] );
3629
if( fitsTcl_histo( curFile, newArgc, newCmd ) != TCL_OK ) {
3634
Tcl_SetResult(curFile->interp, "Unknown 'create' command", TCL_STATIC);
3642
/******************************************************************
3644
******************************************************************/
3646
int fitsTcl_checksum( FitsFD *curFile, int argc, Tcl_Obj *const argv[] )
3648
static char *checksumList="\n"
3650
"checksum update\n";
3652
char result[16], *opt;
3658
Tcl_SetResult(curFile->interp, checksumList, TCL_STATIC);
3662
opt = Tcl_GetStringFromObj( argv[2], NULL );
3664
if( !strcmp("verify", opt) ) {
3666
/* verify the checksum keyword. */
3667
/* return 1 OK, 0 checksum keyword not present, -1 wrong */
3669
if( ffvcks(curFile->fptr, &datastatus, &hdustatus, &status) ) {
3670
dumpFitsErrStack(curFile->interp, status);
3673
/* Return "minimum" checksum status */
3674
Tcl_SetObjResult(curFile->interp,
3675
Tcl_NewIntObj( hdustatus<datastatus
3676
? hdustatus : datastatus) );
3678
} else if( !strcmp("update", opt) ) {
3680
if( ffpcks(curFile->fptr, &status) ) {
3681
dumpFitsErrStack(curFile->interp, status);
3685
if( fitsUpdateFile(curFile) != TCL_OK ) {
3691
Tcl_SetResult(curFile->interp, "Unknown checksum option", TCL_STATIC);
3699
/******************************************************************
3701
******************************************************************/
3703
int fitsTcl_smooth( FitsFD *curFile, int argc, Tcl_Obj *const argv[] )
3705
static char *smoothList= "\n"
3706
"smooth {width height} filename ?inPrimary? \n";
3719
char outfile[FLEN_FILENAME];
3721
float *data; /* original data */
3722
float *sdata; /* smoothed data */
3724
float nullval = -999; /* null value */
3735
int hdunum, hdutype;
3736
char strtemp[FLEN_FILENAME];
3741
Tcl_SetResult(curFile->interp, smoothList, TCL_STATIC);
3746
Tcl_SetResult(curFile->interp, "Wrong # of args to 'smooth'",
3751
if( curFile->hduType != IMAGE_HDU ) {
3752
Tcl_SetResult(curFile->interp, "Cannot smooth a table", TCL_STATIC);
3757
/* Get the width and height parameters */
3758
if( Tcl_ListObjGetElements(curFile->interp, argv[2], &nwin, &winList)
3760
Tcl_SetResult(curFile->interp,
3761
"Cannot parse the window parameters",
3767
Tcl_SetResult( curFile->interp,
3768
"Window list should be {xwin ywin}",
3773
/* Get the width/height parameters */
3774
if( Tcl_GetIntFromObj( curFile->interp, winList[0], &xwin)
3776
Tcl_SetResult( curFile->interp,
3777
"Error reading the width parameter",
3782
Tcl_SetResult( curFile->interp,
3783
"The width must be a odd number",
3788
if( Tcl_GetIntFromObj( curFile->interp, winList[1], &ywin)
3790
Tcl_SetResult( curFile->interp,
3791
"Error reading the height parameter",
3796
Tcl_SetResult( curFile->interp,
3797
"The height must be a odd number",
3802
/* Get the image output file name */
3803
opt = Tcl_GetStringFromObj( argv[3], NULL );
3805
if( len < FLEN_FILENAME ) {
3806
strcpy(outfile, opt );
3808
Tcl_SetResult( curFile->interp,
3809
"The length of filename is too long. ",
3815
if ( Tcl_GetBooleanFromObj( curFile->interp, argv[4], &canprimary )
3820
/* open the input file */
3821
ffreopen( curFile->fptr, &infptr, &status );
3822
ffmahd( infptr, curFile->chdu, &j, &status );
3824
/*get the image parameter */
3825
ffgipr(infptr, maxaxis, &bitpix, &naxis, naxes, &status);
3827
Tcl_SetResult( curFile->interp,
3828
"The smooth algorithm only supports 2-d images.",
3833
for (i = 2; i < naxis; i++) {
3834
if (naxes[i] > 1 ) {
3835
Tcl_SetResult( curFile->interp,
3836
"The smooth algorithm only supports 2-d images.",
3842
ndim = (int)(naxes[0]*naxes[1]);
3843
data = (float *) ckalloc(ndim*sizeof(float ));
3844
sdata = (float *) ckalloc(ndim*sizeof(float ));
3846
ffgpv(infptr,TFLOAT,1, naxes[0]*naxes[1],&nullval, data, &anynul, &status);
3851
/* iterate over y */
3854
for (i=0; i < naxes[1]; i++) {
3855
/* initialize the kernal for this row */
3860
for (k = yl; k <= yh; k++) {
3861
for ( l = xl; l <= xh; l++) {
3862
id = k * naxes[0] + l;
3863
if(data[id]!=nullval) {
3870
/* iterate over x */
3871
for (j = 0; j < naxes[0]; j++) {
3874
sdata[id] = nullval;
3876
sdata[id] = sum/(float )npix;
3879
/* increase the x by 1 */
3881
for ( k = yl; k <= yh; k++) {
3883
if(data[id]!=nullval) {
3890
if(xh + 1< naxes[0] ) {
3892
for ( k = yl; k <= yh; k++) {
3894
if(data[id]!=nullval) {
3902
/* increase the y by 1 */
3903
if (i - yl == yd ) yl++;
3904
if (yh + 1 < naxes[1]) yh++;
3907
/* open the output file */
3908
ffopen(&outfptr, outfile,READWRITE, &status);
3909
if(status == FILE_NOT_OPENED) {
3911
ffinit(&outfptr,outfile,&status);
3913
ffcrim(outfptr,FLOAT_IMG,0,NULL,&status);
3914
} else if (status) {
3915
strcpy(strtemp,"Error opening output file: ");
3916
strcat(strtemp,curFile->fileName);
3917
Tcl_SetResult( curFile->interp,
3924
/* ffcrim(outfptr,FLOAT_IMG, naxis, naxes, &status); */
3925
ffcphd(infptr,outfptr,&status);
3927
/* Update keywords */
3928
ffghdn(outfptr, &hdunum);
3930
ffuky(outfptr,TINT, "BITPIX",&i, NULL, &status);
3931
ffpky(outfptr,TINT, "XWIN",&xwin,"x-width of the smoothing window", &status);
3932
ffpky(outfptr,TINT, "YWIN",&ywin,"y-width of the smoothing window", &status);
3933
strcpy(strtemp,"Smoothed output of the image file: ");
3934
strcat(strtemp,curFile->fileName);
3935
ffpcom(outfptr,strtemp, &status);
3938
ffppn(outfptr,TFLOAT,1,naxes[0]*naxes[1],sdata,&nullval,&status);
3944
ffclos(infptr,&status);
3945
ffclos(outfptr,&status);