diff options
Diffstat (limited to 'silx/io/specfile/src/sfindex.c')
-rw-r--r-- | silx/io/specfile/src/sfindex.c | 551 |
1 files changed, 551 insertions, 0 deletions
diff --git a/silx/io/specfile/src/sfindex.c b/silx/io/specfile/src/sfindex.c new file mode 100644 index 0000000..fd0c7c3 --- /dev/null +++ b/silx/io/specfile/src/sfindex.c @@ -0,0 +1,551 @@ +#/*########################################################################## +# Copyright (C) 2004-2013 European Synchrotron Radiation Facility +# +# This file is part of the PyMca X-ray Fluorescence Toolkit developed at +# the ESRF by the Software group. +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This file is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +#############################################################################*/ +/************************************************************************ + * + * File: sfindex.c + * + * Project: SpecFile library + * + * Description: functions for scan numbering + * + * Author: V.Rey + * + * Date: $Date: 2004/05/12 16:56:47 $ + * + ************************************************************************/ +/* + * Log: $Log: sfindex.c,v $ + * Log: Revision 1.2 2004/05/12 16:56:47 sole + * Log: Support for windows + * Log: + * Log: Revision 1.1 2003/03/06 16:59:05 sole + * Log: Initial revision + * Log: + * Log: Revision 3.0 2000/12/20 14:17:19 rey + * Log: Python version available + * Log: + * Revision 2.1 2000/07/31 19:05:15 19:05:15 rey (Vicente Rey-Bakaikoa) + * SfUpdate and bug corrected in ReadIndex + * + * Revision 2.0 2000/04/13 13:28:54 13:28:54 rey (Vicente Rey-Bakaikoa) + * New version of the library. Complete rewrite + * Adds support for MCA + */ +/* + * File: sfindex.c + * + * Description: + * + * Project: + * + * Author: Vicente Rey Bakaikoa + * + * Date: March 2000 + */ +/* + * $Log: sfindex.c,v $ + * Revision 1.2 2004/05/12 16:56:47 sole + * Support for windows + * + * Revision 1.1 2003/03/06 16:59:05 sole + * Initial revision + * + * Revision 3.0 2000/12/20 14:17:19 rey + * Python version available + * + * Revision 2.1 2000/07/31 19:05:15 19:05:15 rey (Vicente Rey-Bakaikoa) + * SfUpdate and bug corrected in ReadIndex + * + * Revision 2.0 2000/04/13 13:26:55 13:26:55 rey (Vicente Rey-Bakaikoa) + * New version of the library. Complete rewrite + * Adds support for MCA + * + */ + +#include <SpecFile.h> +#include <SpecFileP.h> +#ifdef WIN32 +#include <stdio.h> +#include <stdlib.h> +#else +#include <unistd.h> +#endif +#include <ctype.h> + +#define ON_COMMENT 0 +#define ON_ABO 1 +#define ON_RES 2 +/* + * Declarations + */ +DllExport long * SfList ( SpecFile *sf, int *error ); +DllExport long SfIndexes ( SpecFile *sf, long number, long **idxlist ); +DllExport long SfIndex ( SpecFile *sf, long number, long order ); +DllExport long SfCondList ( SpecFile *sf, long cond, long **scan_list, + int *error ); +DllExport long SfScanNo ( SpecFile *sf ); +DllExport int SfNumberOrder ( SpecFile *sf, long index, long *number, + long *order ); +DllExport long SfNumber ( SpecFile *sf, long index ); +DllExport long SfOrder ( SpecFile *sf, long index ); + +/* + * Internal Functions + */ +static int checkAborted( SpecFile *sf, ObjectList *ptr, int *error ); + + +/********************************************************************* + * Function: long *SfList( sf, error ) + * + * Description: Creates an array with all scan numbers. + * + * Parameters: + * Input : SpecFile pointer + * Returns: + * Array with scan numbers. + * NULL if errors occured. + * Possible errors: + * SF_ERR_MEMORY_ALLOC + * + * Remark: The memory allocated should be freed by the application + * + *********************************************************************/ +DllExport long * +SfList( SpecFile *sf, int *error ) +{ + register ObjectList *ptr; + long *scan_list; + long i = 0; + + scan_list = (long *)malloc( sizeof(long) * (sf->no_scans) ); + + if ( scan_list == (long *)NULL ) { + *error = SF_ERR_MEMORY_ALLOC; + return( scan_list ); + } + + for ( ptr=sf->list.first ; ptr ; ptr=ptr->next ,i++) { + scan_list[i] = ( ((SpecScan *)(ptr->contents))->scan_no ); + } + /*printf("scanlist[%li] = %li\n",i-1,scan_list[i-1]);*/ + return( scan_list ); +} + + +/********************************************************************* + * Function: long SfIndexes( sf, number , idxlist) + * + * Description: Creates an array with all indexes with the same scan + * number. + * + * Parameters: + * Input : SpecFile pointer + * scan number + * Output : array with scan indexes + * Returns: + * Number of indexes found + * Possible errors: + * None possible + * + * Remark: The memory allocated should be freed by the application + * + *********************************************************************/ +DllExport long +SfIndexes( SpecFile *sf, long number, long **idxlist ) +{ + ObjectList *ptr; + long i; + long *indexes; + long *arr; + + i = 0; + indexes = (long *)malloc(sf->no_scans * sizeof(long)); + + for (ptr = sf->list.first; ptr; ptr=ptr->next ) { + if ( number == ((SpecScan *)(ptr->contents))->scan_no) { + indexes[i] = ((SpecScan *)(ptr->contents))->index; + i++; + } + } + + if (i == 0) + arr = (long *) NULL; + else { + arr = (long *)malloc(sizeof(long) * i); + memcpy(arr,indexes,sizeof(long) * i); + } + + *idxlist = arr; + free(indexes); + return( i ); +} + + +/********************************************************************* + * Function: long SfIndex( sf, number, order ) + * + * Description: Gets scan index from scan number and order. + * + * Parameters: + * Input : (1) Scan number + * (2) Scan order + * Returns: + * Index number. + * (-1) if not found. + * + *********************************************************************/ +DllExport long +SfIndex( SpecFile *sf, long number, long order ) +{ + ObjectList *ptr; + + ptr = findScanByNo( &(sf->list), number, order ); + if ( ptr != (ObjectList *)NULL ) + return( ((SpecScan *)(ptr->contents))->index ); + + return( -1 ); +} + + +/********************************************************************* + * Function: long SfCondList( sf, cond, scan_list, error ) + * + * Description: Creates an array with all scan numbers. + * + * Parameters: + * Input : (1) SpecFile pointer + * (2) Condition : 0 => not aborted scans ( NOT_ABORTED ) + * -1 => aborted scans ( ABORTED ) + * nn => more than 'nn' data lines + * Output: (3) Scan list + * (4) error code + * Returns: + * Number of found scans. + * ( -1 ) if errors occured. + * Possible errors: + * SF_ERR_MEMORY_ALLOC + * + * Remark: The memory allocated should be freed by the application + * + *********************************************************************/ +DllExport long +SfCondList( SpecFile *sf, long cond, long **scan_list, int *error ) +{ + register ObjectList *ptr; + long *list; + long i = 0; + int retcheck; + long index; + + *scan_list = (long *)NULL; + + list = (long *)malloc( sizeof(long) * (sf->no_scans) ); + + if ( list == (long *)NULL ) { + *error = SF_ERR_MEMORY_ALLOC; + return( -1 ); + } + + /* + * Aborted scans . + */ + if ( cond < 0 ) { /* aborted scans */ + for ( ptr=sf->list.first ; ptr ; ptr=ptr->next ) { + + retcheck = checkAborted( sf, ptr, error ); + + if ( retcheck < 0 ) { + free( list ); + return( -1 ); + } else if ( retcheck > 0) { + list[i] = ( ((SpecScan *)(ptr->contents))->scan_no ); + i++; + } + } + } else if ( cond == 0 ) { /* not aborted scans */ + for ( ptr=sf->list.first ; ptr ; ptr=ptr->next ) { + + retcheck = checkAborted( sf, ptr, error ); + + if ( retcheck < 0 ) { + free( list ); + return( -1 ); + } else if ( retcheck == 0 ) { + list[i] = ( ((SpecScan *)(ptr->contents))->scan_no ); + i++; + } + } + } else { /* cond > 0 - more than n data_lines */ + for ( ptr=sf->list.first ; ptr ; ptr=ptr->next ) { + + index = ( ((SpecScan *)(ptr->contents))->index ); + if ( SfNoDataLines(sf,index,error) <= cond ) continue; + + list[i] = ( ((SpecScan *)(ptr->contents))->scan_no ); + i++; + } + } + + *scan_list = ( long * ) malloc ( i * sizeof(long)); + + if ( *scan_list == (long *)NULL ) { + *error = SF_ERR_MEMORY_ALLOC; + return( -1 ); + } + + memcpy(*scan_list,list, i * sizeof(long)); + free(list); + + return( i ); +} + + +/********************************************************************* + * Function: long SfScanNo( sf ) + * + * Description: Gets number of scans. + * + * Parameters: + * Input :(1) SpecFile pointer + * Returns: + * Number of scans. + * + *********************************************************************/ +DllExport long +SfScanNo( SpecFile *sf ) +{ + return( sf->no_scans ); +} + + +/********************************************************************* + * Function: int SfNumberOrder( sf, index, number, order ) + * + * Description: Gets scan number and order from index. + * + * Parameters: + * Input : + * (1) SpecFile pointer + * (2) Scan index + * Output: + * (3) Scan number + * (4) Scan order + * Returns: + * ( -1 ) => not found + * ( 0 ) => found + * + *********************************************************************/ +DllExport int +SfNumberOrder( SpecFile *sf, long index, long *number, long *order ) +{ + register ObjectList *list; + + *number = -1; + *order = -1; + + /* + * Find scan . + */ + list = findScanByIndex( &(sf->list), index ); + if ( list == (ObjectList *)NULL ) return( -1 ); + + *number = ((SpecScan *)list->contents)->scan_no; + *order = ((SpecScan *)list->contents)->order; + + return( 0 ); +} + + +/********************************************************************* + * Function: long SfNumber( sf, index ) + * + * Description: Gets scan number from index. + * + * Parameters: + * Input : (1) SpecFile pointer + * (2) Scan index + * Returns: + * Scan number. + * ( -1 ) => not found + * + *********************************************************************/ +DllExport long +SfNumber( SpecFile *sf, long index ) +{ + register ObjectList *list; + + /* + * Find scan . + */ + list = findScanByIndex( &(sf->list), index ); + if ( list == (ObjectList *)NULL ) return( -1 ); + + return( ((SpecScan *)list->contents)->scan_no ); +} + + +/********************************************************************* + * Function: long SfOrder( sf, index ) + * + * Description: Gets scan order from index. + * + * Parameters: + * Input : (1) SpecFile pointer + * (2) Scan index + * Returns: + * Scan order. + * ( -1 ) => not found + * + *********************************************************************/ +DllExport long +SfOrder( SpecFile *sf, long index ) +{ + register ObjectList *list; + + + /* + * Find scan . + */ + list = findScanByIndex( &(sf->list), index ); + if ( list == (ObjectList *)NULL ) return( -1 ); + + return( ((SpecScan *)list->contents)->order ); +} + +/********************************************************************* + * Function: int checkAborted( sf, ptr, error ) + * + * Description: Checks if scan was aborted or not . + * + * Parameters: + * Input : (1) SpecScan pointer + * (2) Pointer to the scan + * Output: (3) Error number + * Returns: + * (-1 ) : error + * ( 0 ) : not aborted + * ( 1 ) : aborted + * Possible errors: + * SF_ERR_MEMORY_ALLOC | => readHeader() + * SF_ERR_FILE_READ + * + *********************************************************************/ +static int +checkAborted( SpecFile *sf, ObjectList *ptr, int *error ) +{ + long nbytes; + long data_lines,size,from; + SpecScan *scan; + char *buffer,*cptr,next; + int state=ON_COMMENT; + int aborted=0; + long index; + + scan = ptr->contents; + index = scan->index; + + data_lines = SfNoDataLines(sf,index,error); + + if ( scan->hdafter_offset == -1 && data_lines > 0) { + return(0); + } else if ( data_lines <= 0 ) { + /* + * maybe aborted on first point + * we have to all to know ( but no data anyway ) + */ + size = scan->size; + from = scan->offset; + } else { + size = scan->last - scan->hdafter_offset; + from = scan->hdafter_offset; + } + + lseek(sf->fd,from,SEEK_SET); + buffer = ( char * ) malloc (size); + nbytes = read(sf->fd,buffer,size); + + if (nbytes == -1 ) { + *error = SF_ERR_FILE_READ; + return(-1); + } + + if (buffer[0] == '#' && buffer[1] == 'C') { + state = ON_COMMENT; + } + + for ( cptr = buffer + 1; cptr < buffer + nbytes - 1; cptr++) { + /* + * Comment line + */ + if ( *cptr == '#' && *(cptr+1) == 'C' && *(cptr-1) == '\n') { + state = ON_COMMENT; + } + /* + * Check aborted + */ + if ( *(cptr-1) == 'a' && *cptr == 'b' && *(cptr+1) == 'o') { + if ( state == ON_COMMENT ) { + state = ON_ABO; + } + } + if ( *(cptr-1) == 'r' && *cptr == 't' && *(cptr+1) == 'e') { + if ( state == ON_ABO) { + aborted = 1; + } + } + /* + * Check resume line + */ + if ( *(cptr-1) == 'r' && *cptr == 'e' && *(cptr+1) == 's') { + if ( state == ON_COMMENT ) { + state = ON_RES; + } + } + if ( *(cptr-1) == 'u' && *cptr == 'm' && *(cptr+1) == 'e') { + if ( state == ON_RES) { + aborted = 0; + } + } + + /* + * If data line... aborted is aborted + */ + if ( *cptr == '\n' ) { + next = *(cptr+1); + if (isdigit(next) || next == '+' || next == '-' || next == '@') { + aborted = 0; + } + } + } + free(buffer); + return(aborted); + +/* + * To be implemented + * - return 0 = not aborted + * - return 1 = aborted + * - return -1 = error + * + * implementation: read whole scan + * - go to header after offset + * - read all till end of scan with size + * - search for a line with a) #C ( comment ) then "aborted" + */ + return( 0 ); +} |