Changeset 1385
- Timestamp:
- Aug 4, 2004, 1:37:39 PM (22 years ago)
- Location:
- trunk/psLib/src
- Files:
-
- 81 edited
-
astro/psCoord.c (modified) (16 diffs)
-
astro/psCoord.h (modified) (7 diffs)
-
astro/psTime.c (modified) (5 diffs)
-
astro/psTime.h (modified) (1 diff)
-
astronomy/psAstrometry.c (modified) (14 diffs)
-
astronomy/psAstrometry.h (modified) (8 diffs)
-
astronomy/psCoord.c (modified) (16 diffs)
-
astronomy/psCoord.h (modified) (7 diffs)
-
astronomy/psMetadata.c (modified) (18 diffs)
-
astronomy/psMetadata.h (modified) (3 diffs)
-
astronomy/psPhotometry.h (modified) (3 diffs)
-
astronomy/psTime.c (modified) (5 diffs)
-
astronomy/psTime.h (modified) (1 diff)
-
collections/psArray.c (modified) (2 diffs)
-
collections/psBitSet.c (modified) (3 diffs)
-
collections/psList.c (modified) (3 diffs)
-
collections/psMetadata.c (modified) (18 diffs)
-
collections/psMetadata.h (modified) (3 diffs)
-
collections/psScalar.c (modified) (1 diff)
-
collections/psScalar.h (modified) (1 diff)
-
collections/psVector.c (modified) (8 diffs)
-
collections/psVector.h (modified) (1 diff)
-
dataManip/psFFT.c (modified) (21 diffs)
-
dataManip/psFFT.h (modified) (1 diff)
-
dataManip/psFunctions.c (modified) (1 diff)
-
dataManip/psFunctions.h (modified) (14 diffs)
-
dataManip/psMatrix.c (modified) (4 diffs)
-
dataManip/psMatrixVectorArithmetic.c (modified) (5 diffs)
-
dataManip/psMinimize.c (modified) (1 diff)
-
dataManip/psStats.c (modified) (44 diffs)
-
dataManip/psStats.h (modified) (1 diff)
-
dataManip/psVectorFFT.c (modified) (21 diffs)
-
dataManip/psVectorFFT.h (modified) (1 diff)
-
fft/psVectorFFT.c (modified) (21 diffs)
-
fft/psVectorFFT.h (modified) (1 diff)
-
image/psImage.c (modified) (1 diff)
-
image/psImage.h (modified) (1 diff)
-
image/psImageExtraction.c (modified) (9 diffs)
-
image/psImageIO.c (modified) (2 diffs)
-
image/psImageManip.c (modified) (2 diffs)
-
image/psImageStats.c (modified) (1 diff)
-
imageops/psImageStats.c (modified) (1 diff)
-
math/psMatrix.c (modified) (4 diffs)
-
math/psMinimize.c (modified) (1 diff)
-
math/psPolynomial.c (modified) (1 diff)
-
math/psPolynomial.h (modified) (14 diffs)
-
math/psSpline.c (modified) (1 diff)
-
math/psSpline.h (modified) (14 diffs)
-
math/psStats.c (modified) (44 diffs)
-
math/psStats.h (modified) (1 diff)
-
mathtypes/psImage.c (modified) (1 diff)
-
mathtypes/psImage.h (modified) (1 diff)
-
mathtypes/psScalar.c (modified) (1 diff)
-
mathtypes/psScalar.h (modified) (1 diff)
-
mathtypes/psVector.c (modified) (8 diffs)
-
mathtypes/psVector.h (modified) (1 diff)
-
sys/psAbort.c (modified) (1 diff)
-
sys/psError.c (modified) (1 diff)
-
sys/psLogMsg.c (modified) (3 diffs)
-
sys/psLogMsg.h (modified) (1 diff)
-
sys/psMemory.c (modified) (24 diffs)
-
sys/psMemory.h (modified) (1 diff)
-
sys/psString.c (modified) (1 diff)
-
sys/psTrace.c (modified) (1 diff)
-
sys/psType.h (modified) (2 diffs)
-
sysUtils/psAbort.c (modified) (1 diff)
-
sysUtils/psError.c (modified) (1 diff)
-
sysUtils/psHash.c (modified) (13 diffs)
-
sysUtils/psHash.h (modified) (1 diff)
-
sysUtils/psLogMsg.c (modified) (3 diffs)
-
sysUtils/psLogMsg.h (modified) (1 diff)
-
sysUtils/psMemory.c (modified) (24 diffs)
-
sysUtils/psMemory.h (modified) (1 diff)
-
sysUtils/psString.c (modified) (1 diff)
-
sysUtils/psTrace.c (modified) (1 diff)
-
sysUtils/psType.h (modified) (2 diffs)
-
types/psArray.c (modified) (2 diffs)
-
types/psBitSet.c (modified) (3 diffs)
-
types/psList.c (modified) (3 diffs)
-
types/psMetadata.c (modified) (18 diffs)
-
types/psMetadata.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/astro/psCoord.c
r1374 r1385 10 10 * @author George Gusciora, MHPCC 11 11 * 12 * @version $Revision: 1. 8$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-08-04 00:55:17$12 * @version $Revision: 1.9 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2004-08-04 23:37:39 $ 14 14 * 15 15 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 33 33 { 34 34 if ( out == NULL ) { 35 out = ( psPlane * ) psAlloc( sizeof( psPlane ) );36 }35 out = ( psPlane * ) psAlloc( sizeof( psPlane ) ); 36 } 37 37 out->x = transform->x->coeff[ 0 ][ 0 ] + 38 38 ( transform->x->coeff[ 1 ][ 0 ] * coords->x ) + 39 39 ( transform->x->coeff[ 0 ][ 1 ] * coords->y ); 40 40 41 41 out->y = transform->y->coeff[ 0 ][ 0 ] + 42 42 ( transform->y->coeff[ 1 ][ 0 ] * coords->x ) + 43 43 ( transform->y->coeff[ 0 ][ 1 ] * coords->y ); 44 44 45 45 return ( out ); 46 46 } … … 56 56 { 57 57 if ( out == NULL ) { 58 out = ( psPlane * ) psAlloc( sizeof( psPlane ) );59 }60 58 out = ( psPlane * ) psAlloc( sizeof( psPlane ) ); 59 } 60 61 61 out->x = transform->x->coeff[ 0 ][ 0 ][ 0 ][ 0 ] + 62 62 ( transform->x->coeff[ 1 ][ 0 ][ 0 ][ 0 ] * coords->x ) + … … 64 64 ( transform->x->coeff[ 0 ][ 0 ][ 1 ][ 0 ] * term3 ) + 65 65 ( transform->x->coeff[ 0 ][ 0 ][ 0 ][ 1 ] * term4 ); 66 66 67 67 out->y = transform->y->coeff[ 0 ][ 0 ][ 0 ][ 0 ] + 68 68 ( transform->y->coeff[ 1 ][ 0 ][ 0 ][ 0 ] * coords->x ) + … … 70 70 ( transform->y->coeff[ 0 ][ 0 ][ 1 ][ 0 ] * term3 ) + 71 71 ( transform->y->coeff[ 0 ][ 0 ][ 0 ][ 1 ] * term4 ); 72 72 73 73 return ( out ); 74 74 } … … 81 81 { 82 82 psSphereTransform * tmp = ( psSphereTransform * ) psAlloc( sizeof( psSphereTransform ) ); 83 83 84 84 tmp->sinPhi = sin( NPlat ); 85 85 tmp->cosPhi = cos( NPlat ); 86 86 tmp->Xo = Xo; 87 87 tmp->xo = xo; 88 88 89 89 return ( tmp ); 90 90 } … … 114 114 double y = 0.0; 115 115 double dx = 0.0; 116 116 117 117 if ( out == NULL ) { 118 out = ( psSphere * ) psAlloc( sizeof( psSphere ) );119 }120 118 out = ( psSphere * ) psAlloc( sizeof( psSphere ) ); 119 } 120 121 121 x = coord->r; 122 122 y = coord->d; … … 127 127 cos( y ); 128 128 cosX = cos( y ) * cos( dx ) / cos( y ); 129 129 130 130 out->r = atan2( sinX, cosX ) + transform->Xo; 131 131 out->d = atan2( sinY, cosY ); 132 132 133 133 return ( out ); 134 134 } … … 142 142 double Xo = 0.0; 143 143 double xo = 0.0; 144 144 145 145 return ( psSphereTransformAlloc( phi, Xo, xo ) ); 146 146 } … … 154 154 double Xo = 0.0; 155 155 double xo = 0.0; 156 156 157 157 return ( psSphereTransformAlloc( phi, Xo, xo ) ); 158 158 } … … 178 178 { 179 179 if ( x > 0 ) { 180 return ( atan( y / x ) ); 181 } else if ( ( x == 0 ) && ( y == 0 ) ) { 180 return ( atan( y / x ) ); 181 } else 182 if ( ( x == 0 ) && ( y == 0 ) ) { 182 183 return ( 0.5 * M_PI ); 183 } else if ( ( x == 0 ) && ( y == 0 ) ) { 184 return ( -0.5 * M_PI ); 185 } else if ( ( x == 0 ) && ( y == 0 ) ) { 186 return ( M_PI + atan( y / x ) ); 187 } else if ( ( x == 0 ) && ( y == 0 ) ) { 188 return ( -M_PI + atan( y / x ) ); 189 } 190 184 } else 185 if ( ( x == 0 ) && ( y == 0 ) ) { 186 return ( -0.5 * M_PI ); 187 } else 188 if ( ( x == 0 ) && ( y == 0 ) ) { 189 return ( M_PI + atan( y / x ) ); 190 } else 191 if ( ( x == 0 ) && ( y == 0 ) ) { 192 return ( -M_PI + atan( y / x ) ); 193 } 194 191 195 psAbort( __func__, "Unacceptable range for (arg(%f, %f).\n", x, y ); 192 196 return ( 0.0 ); … … 201 205 float alpha = 0.0; 202 206 psPlane *tmp = ( psPlane * ) psAlloc( sizeof( psPlane ) ); 203 207 204 208 if ( projection->type == PS_PROJ_TAN ) { 205 R = cot( coord->r ) * ( 180.0 / M_PI ); 206 tmp->x = R * sin( coord->d ); 207 tmp->y = R * cos( coord->d ); 208 209 } else if ( projection->type == PS_PROJ_SIN ) { 209 R = cot( coord->r ) * ( 180.0 / M_PI ); 210 tmp->x = R * sin( coord->d ); 211 tmp->y = R * cos( coord->d ); 212 213 } else 214 if ( projection->type == PS_PROJ_SIN ) { 210 215 R = cos( coord->r ) * ( 180.0 / M_PI ); 211 216 tmp->x = R * sin( coord->d ); 212 217 tmp->y = R * cos( coord->d ); 213 214 } else if ( projection->type == PS_PROJ_CAR ) { 215 tmp->x = coord->d; 216 tmp->y = coord->r; 217 218 } else if ( projection->type == PS_PROJ_MER ) { 219 tmp->x = coord->d; 220 tmp->y = log( tan( 45.0 + ( 0.5 * coord->r ) ) ) * 180.0 / M_PI; 221 222 } else if ( projection->type == PS_PROJ_AIT ) { 223 alpha = 1.0 / ( ( 180.0 / M_PI ) * 224 sqrt( 1.0 + ( cos( coord->r ) * cos( 0.5 * coord->d ) * 0.5 ) ) ); 225 226 tmp->x = 2.0 * alpha * cos( coord->r ) * sin( 0.5 * coord->d ); 227 tmp->y = alpha * sin( coord->d ); 228 229 } else if ( projection->type == PS_PROJ_PAR ) { 230 psAbort( __func__, "The projection type PS_PROJ_PAR is undefined.\n" ); 231 232 } else if ( projection->type == PS_PROJ_GLS ) { 233 psAbort( __func__, "The projection type PS_PROJ_GLS is undefined.\n" ); 234 } 235 218 219 } else 220 if ( projection->type == PS_PROJ_CAR ) { 221 tmp->x = coord->d; 222 tmp->y = coord->r; 223 224 } else 225 if ( projection->type == PS_PROJ_MER ) { 226 tmp->x = coord->d; 227 tmp->y = log( tan( 45.0 + ( 0.5 * coord->r ) ) ) * 180.0 / M_PI; 228 229 } else 230 if ( projection->type == PS_PROJ_AIT ) { 231 alpha = 1.0 / ( ( 180.0 / M_PI ) * 232 sqrt( 1.0 + ( cos( coord->r ) * cos( 0.5 * coord->d ) * 0.5 ) ) ); 233 234 tmp->x = 2.0 * alpha * cos( coord->r ) * sin( 0.5 * coord->d ); 235 tmp->y = alpha * sin( coord->d ); 236 237 } else 238 if ( projection->type == PS_PROJ_PAR ) { 239 psAbort( __func__, "The projection type PS_PROJ_PAR is undefined.\n" ); 240 241 } else 242 if ( projection->type == PS_PROJ_GLS ) { 243 psAbort( __func__, "The projection type PS_PROJ_GLS is undefined.\n" ); 244 } 245 236 246 return ( tmp ); 237 247 } … … 247 257 float chu2 = 0.0; 248 258 psSphere *tmp = ( psSphere * ) psAlloc( sizeof( psSphere ) ); 249 259 250 260 if ( projection->type == PS_PROJ_TAN ) { 251 R = sqrt( ( coord->x * coord->x ) + ( coord->y * coord->y ) ); 252 tmp->d = arg( -coord->y, coord->x ); 253 tmp->r = atan( 180.0 / ( R * M_PI ) ); 254 255 } else if ( projection->type == PS_PROJ_SIN ) { 261 R = sqrt( ( coord->x * coord->x ) + ( coord->y * coord->y ) ); 262 tmp->d = arg( -coord->y, coord->x ); 263 tmp->r = atan( 180.0 / ( R * M_PI ) ); 264 265 } else 266 if ( projection->type == PS_PROJ_SIN ) { 256 267 R = sqrt( ( coord->x * coord->x ) + ( coord->y * coord->y ) ); 257 268 tmp->d = arg( -coord->y, coord->x ); 258 269 tmp->r = acos( ( R * M_PI ) / 180.0 ); 259 260 } else if ( projection->type == PS_PROJ_CAR ) { 261 tmp->d = coord->x; 262 tmp->r = coord->y; 263 264 } else if ( projection->type == PS_PROJ_MER ) { 265 tmp->d = coord->x; 266 tmp->r = ( 2.0 * atan( exp( ( coord->y * M_PI / 180.0 ) ) ) ) - 180.0; 267 268 } else if ( projection->type == PS_PROJ_AIT ) { 269 chu1 = ( coord->x * M_PI ) / 720.0; 270 chu1 *= chu1; 271 chu2 = ( coord->y * M_PI ) / 360.0; 272 chu2 *= chu2; 273 chu = sqrt( 1.0 - chu1 - chu2 ); 274 tmp->d = 2.0 * arg( ( 2.0 * chu * chu ) - 1.0, 275 ( coord->x * chu * M_PI ) / 360.0 ); 276 tmp->r = asin( ( coord->y * chu * M_PI ) / 180.0 ); 277 278 } else if ( projection->type == PS_PROJ_PAR ) { 279 psAbort( __func__, "The projection type PS_PROJ_PAR is undefined.\n" ); 280 281 } else if ( projection->type == PS_PROJ_GLS ) { 282 psAbort( __func__, "The projection type PS_PROJ_GLG is undefined.\n" ); 283 } 284 270 271 } else 272 if ( projection->type == PS_PROJ_CAR ) { 273 tmp->d = coord->x; 274 tmp->r = coord->y; 275 276 } else 277 if ( projection->type == PS_PROJ_MER ) { 278 tmp->d = coord->x; 279 tmp->r = ( 2.0 * atan( exp( ( coord->y * M_PI / 180.0 ) ) ) ) - 180.0; 280 281 } else 282 if ( projection->type == PS_PROJ_AIT ) { 283 chu1 = ( coord->x * M_PI ) / 720.0; 284 chu1 *= chu1; 285 chu2 = ( coord->y * M_PI ) / 360.0; 286 chu2 *= chu2; 287 chu = sqrt( 1.0 - chu1 - chu2 ); 288 tmp->d = 2.0 * arg( ( 2.0 * chu * chu ) - 1.0, 289 ( coord->x * chu * M_PI ) / 360.0 ); 290 tmp->r = asin( ( coord->y * chu * M_PI ) / 180.0 ); 291 292 } else 293 if ( projection->type == PS_PROJ_PAR ) { 294 psAbort( __func__, "The projection type PS_PROJ_PAR is undefined.\n" ); 295 296 } else 297 if ( projection->type == PS_PROJ_GLS ) { 298 psAbort( __func__, "The projection type PS_PROJ_GLG is undefined.\n" ); 299 } 300 285 301 return ( tmp ); 286 302 } … … 298 314 double tmpR = 0.0; 299 315 double tmpD = 0.0; 300 316 301 317 if ( mode == PS_LINEAR ) { 302 // XXX: I have no idea how to construct this. Maybe project both 303 // sperical positions onto the plane, set the origin at one of the 304 // points on the plane, then deproject? 305 306 // XXX: Do I need to somehow scale this projection? 307 // project position1? Will it project to (0.0, 0.0)? 308 proj.R = position1->r; 309 proj.D = position1->d; 310 proj.Xs = 1.0; 311 proj.Ys = 1.0; 312 proj.type = PS_PROJ_TAN; 313 314 // lin = psProject(position2, proj); 315 // tmp = psDeproject(lin, proj); 316 317 // XXX: Do we need to convert units in tmp? 318 return ( tmp ); 319 } else if ( mode == PS_SPHERICAL ) { 318 // XXX: I have no idea how to construct this. Maybe project both 319 // sperical positions onto the plane, set the origin at one of the 320 // points on the plane, then deproject? 321 322 // XXX: Do I need to somehow scale this projection? 323 // project position1? Will it project to (0.0, 0.0)? 324 proj.R = position1->r; 325 proj.D = position1->d; 326 proj.Xs = 1.0; 327 proj.Ys = 1.0; 328 proj.type = PS_PROJ_TAN; 329 330 // lin = psProject(position2, proj); 331 // tmp = psDeproject(lin, proj); 332 333 // XXX: Do we need to convert units in tmp? 334 return ( tmp ); 335 } else 336 if ( mode == PS_SPHERICAL ) { 320 337 tmpR = position2->r - position1->r; 321 338 tmpD = position2->d - position1->d; 322 339 323 340 if ( unit == PS_ARCSEC ) { 324 tmpR = ( tmpR * 180.0 * 60.0 * 60.0 ) / M_PI; 325 tmpD = ( tmpR * 180.0 * 60.0 * 60.0 ) / M_PI; 326 } else if ( unit == PS_ARCMIN ) { 341 tmpR = ( tmpR * 180.0 * 60.0 * 60.0 ) / M_PI; 342 tmpD = ( tmpR * 180.0 * 60.0 * 60.0 ) / M_PI; 343 } else 344 if ( unit == PS_ARCMIN ) { 327 345 tmpR = ( tmpR * 180.0 * 60.0 ) / M_PI; 328 346 tmpD = ( tmpR * 180.0 * 60.0 ) / M_PI; 329 } else if ( unit == PS_DEGREE ) { 330 tmpR = ( tmpR * 180.0 ) / M_PI; 331 tmpD = ( tmpR * 180.0 ) / M_PI; 332 } else if ( unit == PS_RADIAN ) {} 333 else { 334 psAbort( __func__, "Unknown offset unit: 0x%x\n", unit ); 335 } 336 347 } else 348 if ( unit == PS_DEGREE ) { 349 tmpR = ( tmpR * 180.0 ) / M_PI; 350 tmpD = ( tmpR * 180.0 ) / M_PI; 351 } else 352 if ( unit == PS_RADIAN ) {} 353 else { 354 psAbort( __func__, "Unknown offset unit: 0x%x\n", unit ); 355 } 356 337 357 tmp = ( psSphere * ) psAlloc( sizeof( psSphere ) ); 338 358 tmp->r = tmpR; … … 361 381 double tmpR = 0.0; 362 382 double tmpD = 0.0; 363 383 364 384 if ( mode == PS_LINEAR ) { 365 proj.R = position->r; 366 proj.D = position->d; 367 proj.Xs = 1.0; 368 proj.Ys = 1.0; 369 proj.type = PS_PROJ_TAN; 370 371 lin.x = offset->r; 372 lin.y = offset->d; 373 374 tmp = psDeproject( &lin, &proj ); 375 return ( tmp ); 376 377 } else if ( mode == PS_SPHERICAL ) { 385 proj.R = position->r; 386 proj.D = position->d; 387 proj.Xs = 1.0; 388 proj.Ys = 1.0; 389 proj.type = PS_PROJ_TAN; 390 391 lin.x = offset->r; 392 lin.y = offset->d; 393 394 tmp = psDeproject( &lin, &proj ); 395 return ( tmp ); 396 397 } else 398 if ( mode == PS_SPHERICAL ) { 378 399 if ( unit == PS_ARCSEC ) { 379 tmpR = ( M_PI * offset->r ) / ( 180.0 * 60.0 * 60.0 ); 380 tmpD = ( M_PI * offset->d ) / ( 180.0 * 60.0 * 60.0 ); 381 } else if ( unit == PS_ARCMIN ) { 400 tmpR = ( M_PI * offset->r ) / ( 180.0 * 60.0 * 60.0 ); 401 tmpD = ( M_PI * offset->d ) / ( 180.0 * 60.0 * 60.0 ); 402 } else 403 if ( unit == PS_ARCMIN ) { 382 404 tmpR = ( M_PI * offset->r ) / ( 180.0 * 60.0 ); 383 405 tmpD = ( M_PI * offset->d ) / ( 180.0 * 60.0 ); 384 } else if ( unit == PS_DEGREE ) { 385 tmpR = ( M_PI * offset->r ) / ( 180.0 ); 386 tmpD = ( M_PI * offset->d ) / ( 180.0 ); 387 } else if ( unit == PS_RADIAN ) { 388 tmpR = offset->r; 389 tmpD = offset->d; 390 } else { 391 psAbort( __func__, "Unknown offset unit: 0x%x\n", unit ); 392 } 393 406 } else 407 if ( unit == PS_DEGREE ) { 408 tmpR = ( M_PI * offset->r ) / ( 180.0 ); 409 tmpD = ( M_PI * offset->d ) / ( 180.0 ); 410 } else 411 if ( unit == PS_RADIAN ) { 412 tmpR = offset->r; 413 tmpD = offset->d; 414 } else { 415 psAbort( __func__, "Unknown offset unit: 0x%x\n", unit ); 416 } 417 394 418 tmp = ( psSphere * ) psAlloc( sizeof( psSphere ) ); 395 419 tmp->r = position->r + tmpR; … … 397 421 tmp->rErr = 0.0; 398 422 tmp->dErr = 0.0; 399 423 400 424 // XXX: wrap tmp->r and tmp->d to the allowed range (-PI to PI) 401 425 // and (0 to 2*PI). -
trunk/psLib/src/astro/psCoord.h
r1374 r1385 10 10 * @author George Gusciora, MHPCC 11 11 * 12 * @version $Revision: 1. 7$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-08-04 00:55:17$12 * @version $Revision: 1.8 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2004-08-04 23:37:39 $ 14 14 * 15 15 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 30 30 31 31 typedef struct 32 {33 double x; ///< x position34 double y; ///< y position35 double xErr; ///< Error in x position36 double yErr; ///< Error in y position37 }32 { 33 double x; ///< x position 34 double y; ///< y position 35 double xErr; ///< Error in x position 36 double yErr; ///< Error in y position 37 } 38 38 psPlane; 39 39 40 40 typedef struct 41 {42 double r; ///< RA43 double d; ///< Dec44 double rErr; ///< Error in RA45 double dErr; ///< Error in Dec46 }41 { 42 double r; ///< RA 43 double d; ///< Dec 44 double rErr; ///< Error in RA 45 double dErr; ///< Error in Dec 46 } 47 47 psSphere; 48 48 49 49 typedef struct 50 {51 psDPolynomial2D *x;52 psDPolynomial2D *y;53 }50 { 51 psDPolynomial2D *x; 52 psDPolynomial2D *y; 53 } 54 54 psPlaneTransform; 55 55 56 56 typedef struct 57 {58 psDPolynomial4D *x;59 psDPolynomial4D *y;60 }57 { 58 psDPolynomial4D *x; 59 psDPolynomial4D *y; 60 } 61 61 psPlaneDistort; 62 62 63 63 typedef struct 64 {65 double sinPhi; ///< sin of North Pole lattitude66 double cosPhi; ///< cos of North Pole lattitude67 double Xo; ///< First PT of Ares lon68 double xo; ///< First PT of Ares equiv lon69 }64 { 65 double sinPhi; ///< sin of North Pole lattitude 66 double cosPhi; ///< cos of North Pole lattitude 67 double Xo; ///< First PT of Ares lon 68 double xo; ///< First PT of Ares equiv lon 69 } 70 70 psSphereTransform; 71 71 … … 82 82 83 83 typedef struct 84 {85 double R; ///< Coordinates of projection center86 double D; ///< Coordinates of projection center87 double Xs; ///< plate-scale in X direction88 double Ys; ///< plate-scale in Y direction89 psProjectionType type; ///< Projection type90 }84 { 85 double R; ///< Coordinates of projection center 86 double D; ///< Coordinates of projection center 87 double Xs; ///< plate-scale in X direction 88 double Ys; ///< plate-scale in Y direction 89 psProjectionType type; ///< Projection type 90 } 91 91 psProjection; 92 92 … … 106 106 const psPlaneTransform *transform, 107 107 const psPlane *coords ); 108 108 109 109 psPlane *psPlaneDistortApply( psPlane *out, 110 110 const psPlaneDistort *transform, … … 112 112 float term3, 113 113 float term4 ); 114 115 114 115 116 116 // New function prototype. 117 117 psSphereTransform *psSphereTransformAlloc( double NPlat, 118 118 double Xo, 119 119 double xo ); 120 120 121 121 void p_psSphereTransformFree( psSphereTransform *trans ); 122 122 … … 124 124 const psSphereTransform *transform, 125 125 const psSphere *coord ); 126 126 127 127 psSphereTransform *psSphereTransformICRStoEcliptic( psTime time ); 128 128 psSphereTransform *psSphereTransformEcliptictoICRS( psTime time ); … … 132 132 psPlane *psProject( const psSphere *coord, 133 133 const psProjection *projection ); 134 134 135 135 psSphere *psDeproject( const psPlane *coord, 136 136 const psProjection *projection ); 137 137 138 138 psSphere *psSphereGetOffset( const psSphere *restrict position1, 139 139 const psSphere *restrict position2, 140 140 psSphereOffsetMode mode, 141 141 psSphereOffsetUnit unit ); 142 142 143 143 psSphere *psSphereSetOffset( const psSphere *restrict position, 144 144 const psSphere *restrict offset, 145 145 psSphereOffsetMode mode, 146 146 psSphereOffsetUnit unit ); 147 147 148 148 /// @} 149 149 -
trunk/psLib/src/astro/psTime.c
r1272 r1385 12 12 * @author Ross Harman, MHPCC 13 13 * 14 * @version $Revision: 1.1 0$ $Name: not supported by cvs2svn $15 * @date $Date: 2004-0 7-22 21:24:54$14 * @version $Revision: 1.11 $ $Name: not supported by cvs2svn $ 15 * @date $Date: 2004-08-04 23:37:39 $ 16 16 * 17 17 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 100 100 static double leapseconds[NUM_LEAPSECOND_UPDATES][2] = 101 101 { 102 {2441317.5, 10.0}, 103 {2441499.5, 11.0}, 104 {2441683.5, 12.0}, 105 {2442048.5, 13.0}, 106 {2442413.5, 14.0}, 107 {2442778.5, 15.0}, 108 {2443144.5, 16.0}, 109 {2443509.5, 17.0}, 110 {2443874.5, 18.0}, 111 {2444239.5, 19.0}, 112 {2444786.5, 20.0}, 113 {2445151.5, 21.0}, 114 {2445516.5, 22.0}, 115 {2446247.5, 23.0}, 116 {2447161.5, 24.0}, 117 {2447892.5, 25.0}, 118 {2448257.5, 26.0}, 119 {2448804.5, 27.0}, 120 {2449169.5, 28.0}, 121 {2449534.5, 29.0}, 122 {2450083.5, 30.0}, 123 {2450630.5, 31.0}, 124 {2451179.5, 32.0} 102 { 103 2441317.5, 10.0 104 }, 105 { 106 2441499.5, 11.0 107 }, 108 { 109 2441683.5, 12.0 110 }, 111 { 112 2442048.5, 13.0 113 }, 114 { 115 2442413.5, 14.0 116 }, 117 { 118 2442778.5, 15.0 119 }, 120 { 121 2443144.5, 16.0 122 }, 123 { 124 2443509.5, 17.0 125 }, 126 { 127 2443874.5, 18.0 128 }, 129 { 130 2444239.5, 19.0 131 }, 132 { 133 2444786.5, 20.0 134 }, 135 { 136 2445151.5, 21.0 137 }, 138 { 139 2445516.5, 22.0 140 }, 141 { 142 2446247.5, 23.0 143 }, 144 { 145 2447161.5, 24.0 146 }, 147 { 148 2447892.5, 25.0 149 }, 150 { 151 2448257.5, 26.0 152 }, 153 { 154 2448804.5, 27.0 155 }, 156 { 157 2449169.5, 28.0 158 }, 159 { 160 2449534.5, 29.0 161 }, 162 { 163 2450083.5, 30.0 164 }, 165 { 166 2450630.5, 31.0 167 }, 168 { 169 2451179.5, 32.0 170 } 125 171 }; 126 172 … … 395 441 psError(__func__,"Null value for timeval arg not allowed"); 396 442 return outTime; 397 } else if(time->tv_sec < 0) 398 { 399 psError(__func__,"Negative seconds are not allowed: %ld", time->tv_sec); 400 return outTime; 401 } else if(time->tv_usec<0) 402 { 403 psError(__func__,"Negative microseconds are not allowed: %ld", time->tv_usec); 404 return outTime; 405 } 443 } else 444 if(time->tv_sec < 0) 445 { 446 psError(__func__,"Negative seconds are not allowed: %ld", time->tv_sec); 447 return outTime; 448 } else 449 if(time->tv_usec<0) 450 { 451 psError(__func__,"Negative microseconds are not allowed: %ld", time->tv_usec); 452 return outTime; 453 } 406 454 407 455 // Convert to psTime/TAI … … 420 468 int n; 421 469 int y; 422 int mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 470 int mon [] = 471 { 472 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 473 }; 423 474 long epoch; 424 475 psTime outTime; … … 433 484 psError(__func__,"Null value for tm arg not allowed"); 434 485 return outTime; 435 } else if(time->tm_year < 70) 436 { 437 psError(__func__,"Input times earlier than 1970 not allowed. Value: %d", time->tm_year+1900); 438 return outTime; 439 } else if(time->tm_mon<0 || time->tm_mon>11) 440 { 441 psError(__func__,"Month must have a value from 0 to 11. Value: %d", time->tm_mon); 442 return outTime; 443 } else if(time->tm_mday<1 || time->tm_mday>31) 444 { 445 psError(__func__,"Day must have a value from 1 to 31. Value: %d", time->tm_mday); 446 return outTime; 447 } else if(time->tm_hour<0 || time->tm_hour>23) 448 { 449 psError(__func__,"Hour must have a value from 0 to 23. Value: %d", time->tm_hour); 450 return outTime; 451 } else if(time->tm_min<0 || time->tm_min>59) 452 { 453 psError(__func__,"Minute must have a value from 0 to 59. Value: %d", time->tm_min); 454 return outTime; 455 } else if(time->tm_sec<0 || time->tm_sec>59) 456 { 457 psError(__func__,"Second must have a value from 0 to 59. Value: %d", time->tm_sec); 458 return outTime; 459 } 486 } else 487 if(time->tm_year < 70) 488 { 489 psError(__func__,"Input times earlier than 1970 not allowed. Value: %d", time->tm_year+1900); 490 return outTime; 491 } else 492 if(time->tm_mon<0 || time->tm_mon>11) 493 { 494 psError(__func__,"Month must have a value from 0 to 11. Value: %d", time->tm_mon); 495 return outTime; 496 } else 497 if(time->tm_mday<1 || time->tm_mday>31) 498 { 499 psError(__func__,"Day must have a value from 1 to 31. Value: %d", time->tm_mday); 500 return outTime; 501 } else 502 if(time->tm_hour<0 || time->tm_hour>23) 503 { 504 psError(__func__,"Hour must have a value from 0 to 23. Value: %d", time->tm_hour); 505 return outTime; 506 } else 507 if(time->tm_min<0 || time->tm_min>59) 508 { 509 psError(__func__,"Minute must have a value from 0 to 59. Value: %d", time->tm_min); 510 return outTime; 511 } else 512 if(time->tm_sec<0 || time->tm_sec>59) 513 { 514 psError(__func__,"Second must have a value from 0 to 59. Value: %d", time->tm_sec); 515 return outTime; 516 } 460 517 461 518 n = time->tm_year + 1900 - 1; -
trunk/psLib/src/astro/psTime.h
r1256 r1385 12 12 * @author Ross Harman, MHPCC 13 13 * 14 * @version $Revision: 1. 5$ $Name: not supported by cvs2svn $15 * @date $Date: 2004-0 7-22 01:03:00$14 * @version $Revision: 1.6 $ $Name: not supported by cvs2svn $ 15 * @date $Date: 2004-08-04 23:37:39 $ 16 16 * 17 17 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/astronomy/psAstrometry.c
r1382 r1385 8 8 * @author George Gusciora, MHPCC 9 9 * 10 * @version $Revision: 1. 2$ $Name: not supported by cvs2svn $11 * @date $Date: 2004-08-04 2 2:11:09 $10 * @version $Revision: 1.3 $ $Name: not supported by cvs2svn $ 11 * @date $Date: 2004-08-04 23:37:39 $ 12 12 * 13 13 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 30 30 { 31 31 psExposure * exp = psAlloc( sizeof( psExposure ) ); 32 32 33 33 *( double* ) & exp->ra = ra; 34 34 *( double* ) & exp->dec = dec; … … 43 43 *( float* ) & exp->humidity = humidity; 44 44 *( float* ) & exp->exposureTime = exposureTime; 45 45 46 46 return exp; 47 47 48 48 } 49 49 … … 85 85 *( double* ) & grommit->longitudeOffset = exp->ra; // XXX Is this correct? 86 86 *( double* ) & grommit->siderealTime = 0.0; 87 87 88 88 psFree( slaGrommit ); 89 89 return ( grommit ); … … 101 101 psChip * tmpChip = NULL; 102 102 psCell *tmpCell = NULL; 103 103 104 104 tmpChip = psChipinFPA( tmpChip, coord, FPA ); 105 105 tmpCell = psCellinChip( tmpCell, coord, tmpChip ); … … 120 120 int nChips = chips->n; 121 121 psPlane* tmpCoord = NULL; 122 122 123 123 for ( int i = 0; i < nChips; i++ ) { 124 psChip* tmpChip = chips->data[ i ]; 125 tmpCoord = psPlaneTransformApply( tmpCoord, tmpChip->fromFPA, coord ); 126 if ( checkValidChipCoords( tmpCoord->x, tmpCoord->y, 127 tmpChip ) ) { 128 psFree( tmpCoord ); 129 // XXX: George, you didn't use the out parameter! 130 return ( tmpChip ); 131 } 124 psChip* tmpChip = chips->data[ i ]; 125 tmpCoord = psPlaneTransformApply( tmpCoord, tmpChip->fromFPA, coord ); 126 if ( checkValidChipCoords( tmpCoord->x, tmpCoord->y, 127 tmpChip ) ) { 132 128 psFree( tmpCoord ); 129 // XXX: George, you didn't use the out parameter! 130 return ( tmpChip ); 133 131 } 132 psFree( tmpCoord ); 133 } 134 134 psFree( tmpCoord ); 135 135 return ( NULL ); … … 142 142 ( y < 0.0 ) || 143 143 ( y > ( double ) tmpImage->numRows ) ) { 144 return ( 0 );145 }144 return ( 0 ); 145 } 146 146 return ( 1 ); 147 147 } … … 166 166 psPlane * tmpCoord = NULL; 167 167 psArray* cells; 168 168 169 169 if ( chip == NULL ) { 170 return NULL; 170 return NULL; 171 } 172 173 cells = chip->cells; 174 175 if ( cells == NULL ) { 176 return NULL; 177 } 178 179 for ( int i = 0; i < cells->n; i++ ) { 180 psCell* tmpCell = ( psCell* ) cells->data[ i ]; 181 psArray* readouts = tmpCell->readouts; 182 if ( readouts != NULL ) { 183 for ( int j = 0; j < readouts->n; j++ ) { 184 psReadout* tmpReadout = readouts->data[ j ]; 185 tmpCoord = psPlaneTransformApply( tmpCoord, tmpCell->fromChip, coord ); 186 if ( checkValidImageCoords( tmpCoord->x, tmpCoord->y, 187 tmpReadout->image ) ) { 188 return ( tmpCell ); 189 } 190 } 171 191 } 172 173 cells = chip->cells; 174 175 if ( cells == NULL ) { 176 return NULL; 177 } 178 179 for ( int i = 0; i < cells->n; i++ ) { 180 psCell* tmpCell = ( psCell* ) cells->data[ i ]; 181 psArray* readouts = tmpCell->readouts; 182 if ( readouts != NULL ) { 183 for ( int j = 0; j < readouts->n; j++ ) { 184 psReadout* tmpReadout = readouts->data[ j ]; 185 tmpCoord = psPlaneTransformApply( tmpCoord, tmpCell->fromChip, coord ); 186 if ( checkValidImageCoords( tmpCoord->x, tmpCoord->y, 187 tmpReadout->image ) ) { 188 return ( tmpCell ); 189 } 190 } 191 } 192 } 192 } 193 193 return ( NULL ); 194 194 } … … 229 229 sla_OAPQK(TYPE, OB1, OB2, *grommit, &RAP, &DAP); 230 230 */ 231 231 232 232 return ( out ); 233 233 } … … 253 253 psFPA *parFPA = ( cell->parent ) ->parent; 254 254 psGrommit *tmpGrommit = NULL; 255 255 256 256 tmp1 = psPlaneTransformApply( tmp1, cell->toFPA, in ); 257 257 tmp2 = psPlaneTransformApply( tmp2, parFPA->toTangentPlane, tmp1 ); 258 258 tmpGrommit = psGrommitAlloc( parFPA->exposure ); 259 259 tmp3 = psCoordTPtoSky( out, tmp2, psGrommit ); 260 260 261 261 psFree( tmp1 ); 262 262 psFree( tmp2 ); 263 263 psFree( tmpGrommit ); 264 264 265 265 return ( psCoordTPtoSky( out, tmp2, psGrommit ) ); 266 266 267 267 } 268 268 … … 272 272 { 273 273 psPlane * tmp1 = NULL; 274 274 275 275 tmp1 = psPlaneTransformApply( tmp1, cell->toSky, in ); 276 276 277 277 //XXX: Do something to convert the linear coords in tmp1 to spherical 278 278 // coords in out. 279 279 280 280 psFree( tmp1 ); 281 281 282 282 return ( out ); 283 283 } … … 294 294 double DOB; 295 295 double ROB; 296 296 297 297 if ( out == NULL ) { 298 out = ( psPlane * ) psAlloc( sizeof( psPlane ) );299 }300 298 out = ( psPlane * ) psAlloc( sizeof( psPlane ) ); 299 } 300 301 301 sla_AOPQK( psSphere->r, psSphere->d, *grommit, &AOB, &ZOB, &HOB, &DOB, &ROB ); 302 302 out->x = XXX; … … 335 335 out = psCoordFPAtoChip( out, out, whichChip ); 336 336 out = psCoordChiptoCell( out, out, whichCell ); 337 337 338 338 return ( out ); 339 339 } … … 344 344 { 345 345 if ( out == NULL ) { 346 out = ( psPlane * ) psAlloc( sizeof( psPlane ) );347 }348 349 return ( out ); 350 } 351 352 353 354 346 out = ( psPlane * ) psAlloc( sizeof( psPlane ) ); 347 } 348 349 return ( out ); 350 } 351 352 353 354 -
trunk/psLib/src/astronomy/psAstrometry.h
r1384 r1385 8 8 * @author George Gusciora, MHPCC 9 9 * 10 * @version $Revision: 1. 3$ $Name: not supported by cvs2svn $11 * @date $Date: 2004-08-04 23: 12:34$10 * @version $Revision: 1.4 $ $Name: not supported by cvs2svn $ 11 * @date $Date: 2004-08-04 23:37:39 $ 12 12 * 13 13 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 43 43 */ 44 44 typedef struct 45 {46 const double latitude; ///< geodetic latitude (radians)47 const double sinLat; ///< sine of geodetic latitude48 const double cosLat; ///< cosine of geodetic latitude49 const double abberationMag; ///< magnitude of diurnal aberration vector50 const double height; ///< height (HM)51 const double temperature; ///< ambient temperature (TDK)52 const double pressure; ///< pressure (PMB)53 const double humidity; ///< relative humidity (RH)54 const double wavelength; ///< wavelength (WL)55 const double lapseRate; ///< lapse rate (TLR)56 const double refractA; ///< refraction constant A (radians)57 const double refractB; ///< refraction constant B (radians)58 const double longitudeOffset; ///< longitude + ... (radians)59 const double siderealTime; ///< local apparent sidereal time (radians)60 }45 { 46 const double latitude; ///< geodetic latitude (radians) 47 const double sinLat; ///< sine of geodetic latitude 48 const double cosLat; ///< cosine of geodetic latitude 49 const double abberationMag; ///< magnitude of diurnal aberration vector 50 const double height; ///< height (HM) 51 const double temperature; ///< ambient temperature (TDK) 52 const double pressure; ///< pressure (PMB) 53 const double humidity; ///< relative humidity (RH) 54 const double wavelength; ///< wavelength (WL) 55 const double lapseRate; ///< lapse rate (TLR) 56 const double refractA; ///< refraction constant A (radians) 57 const double refractB; ///< refraction constant B (radians) 58 const double longitudeOffset; ///< longitude + ... (radians) 59 const double siderealTime; ///< local apparent sidereal time (radians) 60 } 61 61 psGrommit; 62 62 … … 71 71 */ 72 72 typedef struct 73 {74 int nX; ///< Number of elements in x direction75 int nY; ///< Number of elements in y direction76 double x0; ///< X Position of 0,0 corner on focal plane77 double y0; ///< Y Position of 0,0 corner on focal plane78 double xScale; ///< Scale of the grid in x direction79 double yScale; ///< Scale of the grid in x direction80 double **x; ///< The grid of offsets in x81 double **y; ///< The grid of offsets in y82 }73 { 74 int nX; ///< Number of elements in x direction 75 int nY; ///< Number of elements in y direction 76 double x0; ///< X Position of 0,0 corner on focal plane 77 double y0; ///< Y Position of 0,0 corner on focal plane 78 double xScale; ///< Scale of the grid in x direction 79 double yScale; ///< Scale of the grid in x direction 80 double **x; ///< The grid of offsets in x 81 double **y; ///< The grid of offsets in y 82 } 83 83 psFixedPattern; 84 84 … … 93 93 */ 94 94 typedef struct 95 {96 const unsigned int colBins; ///< Amount of binning in x-dimension97 const unsigned int rowBins; ///< Amount of binning in y-dimension98 const int col0; ///< Offset from the left of chip.99 const int row0; ///< Offset from the bottom of chip.100 101 psImage* image; ///< imaging area of Readout102 psList* objects; ///< objects derived from Readout103 psMetadata* metadata; ///< readout-level metadata104 }95 { 96 const unsigned int colBins; ///< Amount of binning in x-dimension 97 const unsigned int rowBins; ///< Amount of binning in y-dimension 98 const int col0; ///< Offset from the left of chip. 99 const int row0; ///< Offset from the bottom of chip. 100 101 psImage* image; ///< imaging area of Readout 102 psList* objects; ///< objects derived from Readout 103 psMetadata* metadata; ///< readout-level metadata 104 } 105 105 psReadout; 106 106 … … 115 115 */ 116 116 typedef struct psCell 117 {118 psArray* readouts; ///< readouts from the cell119 psMetadata* metadata; ///< cell-level metadata120 121 psPlaneTransform* toChip; ///< transformations from cell to chip coordinates122 psPlaneTransform* fromChip; ///< transformations from chip to cell coordinates123 psPlaneTransform* toFPA; ///< transformations from cell to FPA coordinates124 psPlaneTransform* toSky; ///< transformations from cell to sky coordinates125 126 struct psChip* parent; ///< chip in which contains this cell127 }117 { 118 psArray* readouts; ///< readouts from the cell 119 psMetadata* metadata; ///< cell-level metadata 120 121 psPlaneTransform* toChip; ///< transformations from cell to chip coordinates 122 psPlaneTransform* fromChip; ///< transformations from chip to cell coordinates 123 psPlaneTransform* toFPA; ///< transformations from cell to FPA coordinates 124 psPlaneTransform* toSky; ///< transformations from cell to sky coordinates 125 126 struct psChip* parent; ///< chip in which contains this cell 127 } 128 128 psCell; 129 129 … … 137 137 */ 138 138 typedef struct psChip 139 {140 psArray* cells; ///< cells in the chip141 psMetadata* metadata; ///< chip-level metadata142 143 psPlaneTransform* toFPA; ///< transformation from chip to FPA coordinates144 psPlaneTransform* fromFPA; ///< transformation from FPA to chip coordinates145 146 struct psFPA* parent; ///< FPA which contains this chip147 }139 { 140 psArray* cells; ///< cells in the chip 141 psMetadata* metadata; ///< chip-level metadata 142 143 psPlaneTransform* toFPA; ///< transformation from chip to FPA coordinates 144 psPlaneTransform* fromFPA; ///< transformation from FPA to chip coordinates 145 146 struct psFPA* parent; ///< FPA which contains this chip 147 } 148 148 psChip; 149 149 … … 162 162 */ 163 163 typedef struct psFPA 164 {165 psArray* chips; ///< chips in the focal plane array166 psMetadata* metadata; ///< focal-plane's metadata167 168 psPlaneDistort* fromTangentPlane; ///< transformation from tangent plane to focal plane169 psPlaneDistort* toTangentPlane; ///< transformation from focal plane to tangent plane170 psFixedPattern* pattern; ///< fixed pattern residual offsets171 172 const struct psExposure* exposure; ///< information about this exposure173 174 psPhotSystem* colorPlus; ///< Color reference175 psPhotSystem* colorMinus; ///< Color reference176 177 float rmsX; ///< RMS for x transformation fits178 float rmsY; ///< RMS for y transformation fits179 float chi2; ///< chi^2 of astrometric solution180 }164 { 165 psArray* chips; ///< chips in the focal plane array 166 psMetadata* metadata; ///< focal-plane's metadata 167 168 psPlaneDistort* fromTangentPlane; ///< transformation from tangent plane to focal plane 169 psPlaneDistort* toTangentPlane; ///< transformation from focal plane to tangent plane 170 psFixedPattern* pattern; ///< fixed pattern residual offsets 171 172 const struct psExposure* exposure; ///< information about this exposure 173 174 psPhotSystem* colorPlus; ///< Color reference 175 psPhotSystem* colorMinus; ///< Color reference 176 177 float rmsX; ///< RMS for x transformation fits 178 float rmsY; ///< RMS for y transformation fits 179 float chi2; ///< chi^2 of astrometric solution 180 } 181 181 psFPA; 182 182 … … 189 189 */ 190 190 typedef struct psExposure 191 {192 const double ra; ///< Telescope boresight, right ascention193 const double dec; ///< Telescope boresight, declination194 const double hourAngle; ///< Hour angle195 const double zenith; ///< Zenith distance196 const double azimuth; ///< Azimuth197 const double localTime; ///< Local Sidereal Time198 const float date; ///< Modified Jullian Date of observation199 const float rotAngle; ///< Rotator position angle200 const float temperature; ///< Air temperature, for estimating refraction201 const float pressure; ///< Air pressure, for calculating refraction202 const float humidity; ///< Relative humidity, for refraction203 const float exposureTime; ///< Exposure time204 205 /* Derived quantities */206 const float positionAngle; ///< Position angle207 const float parallacticAngle; ///< Parallactic angle208 const float airmass; ///< Airmass, calculated from zenith distance209 const float parallacticFactor; ///< Parallactic factor210 const char *cameraName; ///< name of camera which provided exposure211 const char *telescopeName; ///< name of telescope which provided exposure212 }191 { 192 const double ra; ///< Telescope boresight, right ascention 193 const double dec; ///< Telescope boresight, declination 194 const double hourAngle; ///< Hour angle 195 const double zenith; ///< Zenith distance 196 const double azimuth; ///< Azimuth 197 const double localTime; ///< Local Sidereal Time 198 const float date; ///< Modified Jullian Date of observation 199 const float rotAngle; ///< Rotator position angle 200 const float temperature; ///< Air temperature, for estimating refraction 201 const float pressure; ///< Air pressure, for calculating refraction 202 const float humidity; ///< Relative humidity, for refraction 203 const float exposureTime; ///< Exposure time 204 205 /* Derived quantities */ 206 const float positionAngle; ///< Position angle 207 const float parallacticAngle; ///< Parallactic angle 208 const float airmass; ///< Airmass, calculated from zenith distance 209 const float parallacticFactor; ///< Parallactic factor 210 const char *cameraName; ///< name of camera which provided exposure 211 const char *telescopeName; ///< name of telescope which provided exposure 212 } 213 213 psExposure; 214 214 -
trunk/psLib/src/astronomy/psCoord.c
r1374 r1385 10 10 * @author George Gusciora, MHPCC 11 11 * 12 * @version $Revision: 1. 8$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-08-04 00:55:17$12 * @version $Revision: 1.9 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2004-08-04 23:37:39 $ 14 14 * 15 15 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 33 33 { 34 34 if ( out == NULL ) { 35 out = ( psPlane * ) psAlloc( sizeof( psPlane ) );36 }35 out = ( psPlane * ) psAlloc( sizeof( psPlane ) ); 36 } 37 37 out->x = transform->x->coeff[ 0 ][ 0 ] + 38 38 ( transform->x->coeff[ 1 ][ 0 ] * coords->x ) + 39 39 ( transform->x->coeff[ 0 ][ 1 ] * coords->y ); 40 40 41 41 out->y = transform->y->coeff[ 0 ][ 0 ] + 42 42 ( transform->y->coeff[ 1 ][ 0 ] * coords->x ) + 43 43 ( transform->y->coeff[ 0 ][ 1 ] * coords->y ); 44 44 45 45 return ( out ); 46 46 } … … 56 56 { 57 57 if ( out == NULL ) { 58 out = ( psPlane * ) psAlloc( sizeof( psPlane ) );59 }60 58 out = ( psPlane * ) psAlloc( sizeof( psPlane ) ); 59 } 60 61 61 out->x = transform->x->coeff[ 0 ][ 0 ][ 0 ][ 0 ] + 62 62 ( transform->x->coeff[ 1 ][ 0 ][ 0 ][ 0 ] * coords->x ) + … … 64 64 ( transform->x->coeff[ 0 ][ 0 ][ 1 ][ 0 ] * term3 ) + 65 65 ( transform->x->coeff[ 0 ][ 0 ][ 0 ][ 1 ] * term4 ); 66 66 67 67 out->y = transform->y->coeff[ 0 ][ 0 ][ 0 ][ 0 ] + 68 68 ( transform->y->coeff[ 1 ][ 0 ][ 0 ][ 0 ] * coords->x ) + … … 70 70 ( transform->y->coeff[ 0 ][ 0 ][ 1 ][ 0 ] * term3 ) + 71 71 ( transform->y->coeff[ 0 ][ 0 ][ 0 ][ 1 ] * term4 ); 72 72 73 73 return ( out ); 74 74 } … … 81 81 { 82 82 psSphereTransform * tmp = ( psSphereTransform * ) psAlloc( sizeof( psSphereTransform ) ); 83 83 84 84 tmp->sinPhi = sin( NPlat ); 85 85 tmp->cosPhi = cos( NPlat ); 86 86 tmp->Xo = Xo; 87 87 tmp->xo = xo; 88 88 89 89 return ( tmp ); 90 90 } … … 114 114 double y = 0.0; 115 115 double dx = 0.0; 116 116 117 117 if ( out == NULL ) { 118 out = ( psSphere * ) psAlloc( sizeof( psSphere ) );119 }120 118 out = ( psSphere * ) psAlloc( sizeof( psSphere ) ); 119 } 120 121 121 x = coord->r; 122 122 y = coord->d; … … 127 127 cos( y ); 128 128 cosX = cos( y ) * cos( dx ) / cos( y ); 129 129 130 130 out->r = atan2( sinX, cosX ) + transform->Xo; 131 131 out->d = atan2( sinY, cosY ); 132 132 133 133 return ( out ); 134 134 } … … 142 142 double Xo = 0.0; 143 143 double xo = 0.0; 144 144 145 145 return ( psSphereTransformAlloc( phi, Xo, xo ) ); 146 146 } … … 154 154 double Xo = 0.0; 155 155 double xo = 0.0; 156 156 157 157 return ( psSphereTransformAlloc( phi, Xo, xo ) ); 158 158 } … … 178 178 { 179 179 if ( x > 0 ) { 180 return ( atan( y / x ) ); 181 } else if ( ( x == 0 ) && ( y == 0 ) ) { 180 return ( atan( y / x ) ); 181 } else 182 if ( ( x == 0 ) && ( y == 0 ) ) { 182 183 return ( 0.5 * M_PI ); 183 } else if ( ( x == 0 ) && ( y == 0 ) ) { 184 return ( -0.5 * M_PI ); 185 } else if ( ( x == 0 ) && ( y == 0 ) ) { 186 return ( M_PI + atan( y / x ) ); 187 } else if ( ( x == 0 ) && ( y == 0 ) ) { 188 return ( -M_PI + atan( y / x ) ); 189 } 190 184 } else 185 if ( ( x == 0 ) && ( y == 0 ) ) { 186 return ( -0.5 * M_PI ); 187 } else 188 if ( ( x == 0 ) && ( y == 0 ) ) { 189 return ( M_PI + atan( y / x ) ); 190 } else 191 if ( ( x == 0 ) && ( y == 0 ) ) { 192 return ( -M_PI + atan( y / x ) ); 193 } 194 191 195 psAbort( __func__, "Unacceptable range for (arg(%f, %f).\n", x, y ); 192 196 return ( 0.0 ); … … 201 205 float alpha = 0.0; 202 206 psPlane *tmp = ( psPlane * ) psAlloc( sizeof( psPlane ) ); 203 207 204 208 if ( projection->type == PS_PROJ_TAN ) { 205 R = cot( coord->r ) * ( 180.0 / M_PI ); 206 tmp->x = R * sin( coord->d ); 207 tmp->y = R * cos( coord->d ); 208 209 } else if ( projection->type == PS_PROJ_SIN ) { 209 R = cot( coord->r ) * ( 180.0 / M_PI ); 210 tmp->x = R * sin( coord->d ); 211 tmp->y = R * cos( coord->d ); 212 213 } else 214 if ( projection->type == PS_PROJ_SIN ) { 210 215 R = cos( coord->r ) * ( 180.0 / M_PI ); 211 216 tmp->x = R * sin( coord->d ); 212 217 tmp->y = R * cos( coord->d ); 213 214 } else if ( projection->type == PS_PROJ_CAR ) { 215 tmp->x = coord->d; 216 tmp->y = coord->r; 217 218 } else if ( projection->type == PS_PROJ_MER ) { 219 tmp->x = coord->d; 220 tmp->y = log( tan( 45.0 + ( 0.5 * coord->r ) ) ) * 180.0 / M_PI; 221 222 } else if ( projection->type == PS_PROJ_AIT ) { 223 alpha = 1.0 / ( ( 180.0 / M_PI ) * 224 sqrt( 1.0 + ( cos( coord->r ) * cos( 0.5 * coord->d ) * 0.5 ) ) ); 225 226 tmp->x = 2.0 * alpha * cos( coord->r ) * sin( 0.5 * coord->d ); 227 tmp->y = alpha * sin( coord->d ); 228 229 } else if ( projection->type == PS_PROJ_PAR ) { 230 psAbort( __func__, "The projection type PS_PROJ_PAR is undefined.\n" ); 231 232 } else if ( projection->type == PS_PROJ_GLS ) { 233 psAbort( __func__, "The projection type PS_PROJ_GLS is undefined.\n" ); 234 } 235 218 219 } else 220 if ( projection->type == PS_PROJ_CAR ) { 221 tmp->x = coord->d; 222 tmp->y = coord->r; 223 224 } else 225 if ( projection->type == PS_PROJ_MER ) { 226 tmp->x = coord->d; 227 tmp->y = log( tan( 45.0 + ( 0.5 * coord->r ) ) ) * 180.0 / M_PI; 228 229 } else 230 if ( projection->type == PS_PROJ_AIT ) { 231 alpha = 1.0 / ( ( 180.0 / M_PI ) * 232 sqrt( 1.0 + ( cos( coord->r ) * cos( 0.5 * coord->d ) * 0.5 ) ) ); 233 234 tmp->x = 2.0 * alpha * cos( coord->r ) * sin( 0.5 * coord->d ); 235 tmp->y = alpha * sin( coord->d ); 236 237 } else 238 if ( projection->type == PS_PROJ_PAR ) { 239 psAbort( __func__, "The projection type PS_PROJ_PAR is undefined.\n" ); 240 241 } else 242 if ( projection->type == PS_PROJ_GLS ) { 243 psAbort( __func__, "The projection type PS_PROJ_GLS is undefined.\n" ); 244 } 245 236 246 return ( tmp ); 237 247 } … … 247 257 float chu2 = 0.0; 248 258 psSphere *tmp = ( psSphere * ) psAlloc( sizeof( psSphere ) ); 249 259 250 260 if ( projection->type == PS_PROJ_TAN ) { 251 R = sqrt( ( coord->x * coord->x ) + ( coord->y * coord->y ) ); 252 tmp->d = arg( -coord->y, coord->x ); 253 tmp->r = atan( 180.0 / ( R * M_PI ) ); 254 255 } else if ( projection->type == PS_PROJ_SIN ) { 261 R = sqrt( ( coord->x * coord->x ) + ( coord->y * coord->y ) ); 262 tmp->d = arg( -coord->y, coord->x ); 263 tmp->r = atan( 180.0 / ( R * M_PI ) ); 264 265 } else 266 if ( projection->type == PS_PROJ_SIN ) { 256 267 R = sqrt( ( coord->x * coord->x ) + ( coord->y * coord->y ) ); 257 268 tmp->d = arg( -coord->y, coord->x ); 258 269 tmp->r = acos( ( R * M_PI ) / 180.0 ); 259 260 } else if ( projection->type == PS_PROJ_CAR ) { 261 tmp->d = coord->x; 262 tmp->r = coord->y; 263 264 } else if ( projection->type == PS_PROJ_MER ) { 265 tmp->d = coord->x; 266 tmp->r = ( 2.0 * atan( exp( ( coord->y * M_PI / 180.0 ) ) ) ) - 180.0; 267 268 } else if ( projection->type == PS_PROJ_AIT ) { 269 chu1 = ( coord->x * M_PI ) / 720.0; 270 chu1 *= chu1; 271 chu2 = ( coord->y * M_PI ) / 360.0; 272 chu2 *= chu2; 273 chu = sqrt( 1.0 - chu1 - chu2 ); 274 tmp->d = 2.0 * arg( ( 2.0 * chu * chu ) - 1.0, 275 ( coord->x * chu * M_PI ) / 360.0 ); 276 tmp->r = asin( ( coord->y * chu * M_PI ) / 180.0 ); 277 278 } else if ( projection->type == PS_PROJ_PAR ) { 279 psAbort( __func__, "The projection type PS_PROJ_PAR is undefined.\n" ); 280 281 } else if ( projection->type == PS_PROJ_GLS ) { 282 psAbort( __func__, "The projection type PS_PROJ_GLG is undefined.\n" ); 283 } 284 270 271 } else 272 if ( projection->type == PS_PROJ_CAR ) { 273 tmp->d = coord->x; 274 tmp->r = coord->y; 275 276 } else 277 if ( projection->type == PS_PROJ_MER ) { 278 tmp->d = coord->x; 279 tmp->r = ( 2.0 * atan( exp( ( coord->y * M_PI / 180.0 ) ) ) ) - 180.0; 280 281 } else 282 if ( projection->type == PS_PROJ_AIT ) { 283 chu1 = ( coord->x * M_PI ) / 720.0; 284 chu1 *= chu1; 285 chu2 = ( coord->y * M_PI ) / 360.0; 286 chu2 *= chu2; 287 chu = sqrt( 1.0 - chu1 - chu2 ); 288 tmp->d = 2.0 * arg( ( 2.0 * chu * chu ) - 1.0, 289 ( coord->x * chu * M_PI ) / 360.0 ); 290 tmp->r = asin( ( coord->y * chu * M_PI ) / 180.0 ); 291 292 } else 293 if ( projection->type == PS_PROJ_PAR ) { 294 psAbort( __func__, "The projection type PS_PROJ_PAR is undefined.\n" ); 295 296 } else 297 if ( projection->type == PS_PROJ_GLS ) { 298 psAbort( __func__, "The projection type PS_PROJ_GLG is undefined.\n" ); 299 } 300 285 301 return ( tmp ); 286 302 } … … 298 314 double tmpR = 0.0; 299 315 double tmpD = 0.0; 300 316 301 317 if ( mode == PS_LINEAR ) { 302 // XXX: I have no idea how to construct this. Maybe project both 303 // sperical positions onto the plane, set the origin at one of the 304 // points on the plane, then deproject? 305 306 // XXX: Do I need to somehow scale this projection? 307 // project position1? Will it project to (0.0, 0.0)? 308 proj.R = position1->r; 309 proj.D = position1->d; 310 proj.Xs = 1.0; 311 proj.Ys = 1.0; 312 proj.type = PS_PROJ_TAN; 313 314 // lin = psProject(position2, proj); 315 // tmp = psDeproject(lin, proj); 316 317 // XXX: Do we need to convert units in tmp? 318 return ( tmp ); 319 } else if ( mode == PS_SPHERICAL ) { 318 // XXX: I have no idea how to construct this. Maybe project both 319 // sperical positions onto the plane, set the origin at one of the 320 // points on the plane, then deproject? 321 322 // XXX: Do I need to somehow scale this projection? 323 // project position1? Will it project to (0.0, 0.0)? 324 proj.R = position1->r; 325 proj.D = position1->d; 326 proj.Xs = 1.0; 327 proj.Ys = 1.0; 328 proj.type = PS_PROJ_TAN; 329 330 // lin = psProject(position2, proj); 331 // tmp = psDeproject(lin, proj); 332 333 // XXX: Do we need to convert units in tmp? 334 return ( tmp ); 335 } else 336 if ( mode == PS_SPHERICAL ) { 320 337 tmpR = position2->r - position1->r; 321 338 tmpD = position2->d - position1->d; 322 339 323 340 if ( unit == PS_ARCSEC ) { 324 tmpR = ( tmpR * 180.0 * 60.0 * 60.0 ) / M_PI; 325 tmpD = ( tmpR * 180.0 * 60.0 * 60.0 ) / M_PI; 326 } else if ( unit == PS_ARCMIN ) { 341 tmpR = ( tmpR * 180.0 * 60.0 * 60.0 ) / M_PI; 342 tmpD = ( tmpR * 180.0 * 60.0 * 60.0 ) / M_PI; 343 } else 344 if ( unit == PS_ARCMIN ) { 327 345 tmpR = ( tmpR * 180.0 * 60.0 ) / M_PI; 328 346 tmpD = ( tmpR * 180.0 * 60.0 ) / M_PI; 329 } else if ( unit == PS_DEGREE ) { 330 tmpR = ( tmpR * 180.0 ) / M_PI; 331 tmpD = ( tmpR * 180.0 ) / M_PI; 332 } else if ( unit == PS_RADIAN ) {} 333 else { 334 psAbort( __func__, "Unknown offset unit: 0x%x\n", unit ); 335 } 336 347 } else 348 if ( unit == PS_DEGREE ) { 349 tmpR = ( tmpR * 180.0 ) / M_PI; 350 tmpD = ( tmpR * 180.0 ) / M_PI; 351 } else 352 if ( unit == PS_RADIAN ) {} 353 else { 354 psAbort( __func__, "Unknown offset unit: 0x%x\n", unit ); 355 } 356 337 357 tmp = ( psSphere * ) psAlloc( sizeof( psSphere ) ); 338 358 tmp->r = tmpR; … … 361 381 double tmpR = 0.0; 362 382 double tmpD = 0.0; 363 383 364 384 if ( mode == PS_LINEAR ) { 365 proj.R = position->r; 366 proj.D = position->d; 367 proj.Xs = 1.0; 368 proj.Ys = 1.0; 369 proj.type = PS_PROJ_TAN; 370 371 lin.x = offset->r; 372 lin.y = offset->d; 373 374 tmp = psDeproject( &lin, &proj ); 375 return ( tmp ); 376 377 } else if ( mode == PS_SPHERICAL ) { 385 proj.R = position->r; 386 proj.D = position->d; 387 proj.Xs = 1.0; 388 proj.Ys = 1.0; 389 proj.type = PS_PROJ_TAN; 390 391 lin.x = offset->r; 392 lin.y = offset->d; 393 394 tmp = psDeproject( &lin, &proj ); 395 return ( tmp ); 396 397 } else 398 if ( mode == PS_SPHERICAL ) { 378 399 if ( unit == PS_ARCSEC ) { 379 tmpR = ( M_PI * offset->r ) / ( 180.0 * 60.0 * 60.0 ); 380 tmpD = ( M_PI * offset->d ) / ( 180.0 * 60.0 * 60.0 ); 381 } else if ( unit == PS_ARCMIN ) { 400 tmpR = ( M_PI * offset->r ) / ( 180.0 * 60.0 * 60.0 ); 401 tmpD = ( M_PI * offset->d ) / ( 180.0 * 60.0 * 60.0 ); 402 } else 403 if ( unit == PS_ARCMIN ) { 382 404 tmpR = ( M_PI * offset->r ) / ( 180.0 * 60.0 ); 383 405 tmpD = ( M_PI * offset->d ) / ( 180.0 * 60.0 ); 384 } else if ( unit == PS_DEGREE ) { 385 tmpR = ( M_PI * offset->r ) / ( 180.0 ); 386 tmpD = ( M_PI * offset->d ) / ( 180.0 ); 387 } else if ( unit == PS_RADIAN ) { 388 tmpR = offset->r; 389 tmpD = offset->d; 390 } else { 391 psAbort( __func__, "Unknown offset unit: 0x%x\n", unit ); 392 } 393 406 } else 407 if ( unit == PS_DEGREE ) { 408 tmpR = ( M_PI * offset->r ) / ( 180.0 ); 409 tmpD = ( M_PI * offset->d ) / ( 180.0 ); 410 } else 411 if ( unit == PS_RADIAN ) { 412 tmpR = offset->r; 413 tmpD = offset->d; 414 } else { 415 psAbort( __func__, "Unknown offset unit: 0x%x\n", unit ); 416 } 417 394 418 tmp = ( psSphere * ) psAlloc( sizeof( psSphere ) ); 395 419 tmp->r = position->r + tmpR; … … 397 421 tmp->rErr = 0.0; 398 422 tmp->dErr = 0.0; 399 423 400 424 // XXX: wrap tmp->r and tmp->d to the allowed range (-PI to PI) 401 425 // and (0 to 2*PI). -
trunk/psLib/src/astronomy/psCoord.h
r1374 r1385 10 10 * @author George Gusciora, MHPCC 11 11 * 12 * @version $Revision: 1. 7$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-08-04 00:55:17$12 * @version $Revision: 1.8 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2004-08-04 23:37:39 $ 14 14 * 15 15 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 30 30 31 31 typedef struct 32 {33 double x; ///< x position34 double y; ///< y position35 double xErr; ///< Error in x position36 double yErr; ///< Error in y position37 }32 { 33 double x; ///< x position 34 double y; ///< y position 35 double xErr; ///< Error in x position 36 double yErr; ///< Error in y position 37 } 38 38 psPlane; 39 39 40 40 typedef struct 41 {42 double r; ///< RA43 double d; ///< Dec44 double rErr; ///< Error in RA45 double dErr; ///< Error in Dec46 }41 { 42 double r; ///< RA 43 double d; ///< Dec 44 double rErr; ///< Error in RA 45 double dErr; ///< Error in Dec 46 } 47 47 psSphere; 48 48 49 49 typedef struct 50 {51 psDPolynomial2D *x;52 psDPolynomial2D *y;53 }50 { 51 psDPolynomial2D *x; 52 psDPolynomial2D *y; 53 } 54 54 psPlaneTransform; 55 55 56 56 typedef struct 57 {58 psDPolynomial4D *x;59 psDPolynomial4D *y;60 }57 { 58 psDPolynomial4D *x; 59 psDPolynomial4D *y; 60 } 61 61 psPlaneDistort; 62 62 63 63 typedef struct 64 {65 double sinPhi; ///< sin of North Pole lattitude66 double cosPhi; ///< cos of North Pole lattitude67 double Xo; ///< First PT of Ares lon68 double xo; ///< First PT of Ares equiv lon69 }64 { 65 double sinPhi; ///< sin of North Pole lattitude 66 double cosPhi; ///< cos of North Pole lattitude 67 double Xo; ///< First PT of Ares lon 68 double xo; ///< First PT of Ares equiv lon 69 } 70 70 psSphereTransform; 71 71 … … 82 82 83 83 typedef struct 84 {85 double R; ///< Coordinates of projection center86 double D; ///< Coordinates of projection center87 double Xs; ///< plate-scale in X direction88 double Ys; ///< plate-scale in Y direction89 psProjectionType type; ///< Projection type90 }84 { 85 double R; ///< Coordinates of projection center 86 double D; ///< Coordinates of projection center 87 double Xs; ///< plate-scale in X direction 88 double Ys; ///< plate-scale in Y direction 89 psProjectionType type; ///< Projection type 90 } 91 91 psProjection; 92 92 … … 106 106 const psPlaneTransform *transform, 107 107 const psPlane *coords ); 108 108 109 109 psPlane *psPlaneDistortApply( psPlane *out, 110 110 const psPlaneDistort *transform, … … 112 112 float term3, 113 113 float term4 ); 114 115 114 115 116 116 // New function prototype. 117 117 psSphereTransform *psSphereTransformAlloc( double NPlat, 118 118 double Xo, 119 119 double xo ); 120 120 121 121 void p_psSphereTransformFree( psSphereTransform *trans ); 122 122 … … 124 124 const psSphereTransform *transform, 125 125 const psSphere *coord ); 126 126 127 127 psSphereTransform *psSphereTransformICRStoEcliptic( psTime time ); 128 128 psSphereTransform *psSphereTransformEcliptictoICRS( psTime time ); … … 132 132 psPlane *psProject( const psSphere *coord, 133 133 const psProjection *projection ); 134 134 135 135 psSphere *psDeproject( const psPlane *coord, 136 136 const psProjection *projection ); 137 137 138 138 psSphere *psSphereGetOffset( const psSphere *restrict position1, 139 139 const psSphere *restrict position2, 140 140 psSphereOffsetMode mode, 141 141 psSphereOffsetUnit unit ); 142 142 143 143 psSphere *psSphereSetOffset( const psSphere *restrict position, 144 144 const psSphere *restrict offset, 145 145 psSphereOffsetMode mode, 146 146 psSphereOffsetUnit unit ); 147 147 148 148 /// @} 149 149 -
trunk/psLib/src/astronomy/psMetadata.c
r1381 r1385 11 11 * @author Ross Harman, MHPCC 12 12 * 13 * @version $Revision: 1. 7$ $Name: not supported by cvs2svn $14 * @date $Date: 2004-08-04 2 1:05:24$13 * @version $Revision: 1.8 $ $Name: not supported by cvs2svn $ 14 * @date $Date: 2004-08-04 23:37:39 $ 15 15 * 16 16 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 65 65 { 66 66 psMetadataType type; 67 67 68 68 type = metadataItem->type; 69 69 70 70 if ( metadataItem == NULL ) { 71 return ;72 }73 71 return ; 72 } 73 74 74 psFree( metadataItem->name ); 75 75 psFree( metadataItem->comment ); 76 76 psFree( metadataItem->items ); 77 77 78 78 if ( type == PS_META_STR || 79 79 type == PS_META_IMG || … … 82 82 type == PS_META_ASTROM || 83 83 type == PS_META_UNKNOWN ) { 84 psFree( metadataItem->data.V );85 }84 psFree( metadataItem->data.V ); 85 } 86 86 } 87 87 … … 89 89 { 90 90 if ( metadata == NULL ) { 91 return ;92 }91 return ; 92 } 93 93 psFree( metadata->list ); 94 94 psFree( metadata->table ); … … 103 103 va_list argPtr; 104 104 psMetadataItem *metadataItem = NULL; 105 105 106 106 // Get the variable list parameters to pass to allocation function 107 107 va_start( argPtr, comment ); 108 108 109 109 // Call metadata item allocation 110 110 metadataItem = psMetadataItemAllocV( name, type, comment, argPtr ); 111 111 112 112 // Clean up stack after variable arguement has been used 113 113 va_end( argPtr ); 114 114 115 115 return metadataItem; 116 116 } … … 119 119 { 120 120 psMetadataItem * metadataItem = NULL; 121 121 122 122 if ( name == NULL ) { 123 psError( __func__, "Null value for string not allowed" );124 return NULL;125 }126 123 psError( __func__, "Null value for string not allowed" ); 124 return NULL; 125 } 126 127 127 // Allocate metadata item 128 128 metadataItem = ( psMetadataItem * ) psAlloc( sizeof( psMetadataItem ) ); 129 129 if ( metadataItem == NULL ) { 130 psAbort( __func__, "Failed to allocate memory" );131 }132 130 psAbort( __func__, "Failed to allocate memory" ); 131 } 132 133 133 // Set deallocator 134 134 p_psMemSetDeallocator( metadataItem, ( psFreeFcn ) metadataItemFree ); 135 135 136 136 // Allocate and set metadata item comment 137 137 metadataItem->comment = ( char * ) psAlloc( sizeof( char ) * MAX_STRING_LENGTH ); 138 138 if ( comment == NULL ) { 139 // Per SDRS, null isn't allowed, must use "" instead140 strncpy( metadataItem->comment, "", MAX_STRING_LENGTH );141 } else {142 strncpy( metadataItem->comment, comment, MAX_STRING_LENGTH );143 }144 139 // Per SDRS, null isn't allowed, must use "" instead 140 strncpy( metadataItem->comment, "", MAX_STRING_LENGTH ); 141 } else { 142 strncpy( metadataItem->comment, comment, MAX_STRING_LENGTH ); 143 } 144 145 145 // Set metadata item unique id 146 146 *( int* ) ( &metadataItem->id ) = ++metadataId; 147 147 148 148 // Set metadata item type 149 149 metadataItem->type = type; 150 150 151 151 // Set metadata item value 152 152 switch ( type ) { 153 case PS_META_BOOL:154 metadataItem->data.B = ( bool ) va_arg( argPtr, int );155 break;156 case PS_META_S32:157 metadataItem->data.S32 = va_arg( argPtr, psS32 );158 break;159 case PS_META_F32:160 metadataItem->data.F32 = ( psF32 ) va_arg( argPtr, psF64 );161 break;162 case PS_META_F64:163 metadataItem->data.F64 = va_arg( argPtr, psF64 );164 break;165 case PS_META_STR:166 metadataItem->data.V = psStringNCopy( va_arg( argPtr, char* ), MAX_STRING_LENGTH );167 break;168 case PS_META_IMG:169 case PS_META_JPEG:170 case PS_META_PNG:171 case PS_META_ASTROM:172 case PS_META_UNKNOWN:173 default:174 psError( __func__, "Invalid psMetadataType: %d", type );175 }176 153 case PS_META_BOOL: 154 metadataItem->data.B = ( bool ) va_arg( argPtr, int ); 155 break; 156 case PS_META_S32: 157 metadataItem->data.S32 = va_arg( argPtr, psS32 ); 158 break; 159 case PS_META_F32: 160 metadataItem->data.F32 = ( psF32 ) va_arg( argPtr, psF64 ); 161 break; 162 case PS_META_F64: 163 metadataItem->data.F64 = va_arg( argPtr, psF64 ); 164 break; 165 case PS_META_STR: 166 metadataItem->data.V = psStringNCopy( va_arg( argPtr, char* ), MAX_STRING_LENGTH ); 167 break; 168 case PS_META_IMG: 169 case PS_META_JPEG: 170 case PS_META_PNG: 171 case PS_META_ASTROM: 172 case PS_META_UNKNOWN: 173 default: 174 psError( __func__, "Invalid psMetadataType: %d", type ); 175 } 176 177 177 // Allocate and set metadata item name 178 178 metadataItem->name = ( char * ) psAlloc( sizeof( char ) * MAX_STRING_LENGTH ); 179 179 vsprintf( metadataItem->name, name, argPtr ); 180 180 181 181 // Allocate metadata items with same name. 182 182 metadataItem->items = psListAlloc( NULL ); 183 183 184 184 return metadataItem; 185 185 } … … 190 190 psHash *table = NULL; 191 191 psMetadata *metadata = NULL; 192 192 193 193 // Allocate metadata 194 194 metadata = ( psMetadata * ) psAlloc( sizeof( psMetadata ) ); 195 195 if ( metadata == NULL ) { 196 psAbort( __func__, "Failed to allocate metadata" );197 }198 196 psAbort( __func__, "Failed to allocate metadata" ); 197 } 198 199 199 // Set deallocator 200 200 p_psMemSetDeallocator( metadata, ( psFreeFcn ) metadataFree ); 201 201 202 202 // Allocate metadata's internal containers 203 203 list = ( psList * ) psListAlloc( NULL ); 204 204 if ( list == NULL ) { 205 psAbort( __func__, "Failed to allocate list" );206 }207 205 psAbort( __func__, "Failed to allocate list" ); 206 } 207 208 208 table = ( psHash * ) psHashAlloc( 10 ); 209 209 if ( table == NULL ) { 210 psAbort( __func__, "Failed to allocate table" );211 }212 210 psAbort( __func__, "Failed to allocate table" ); 211 } 212 213 213 metadata->list = list; 214 214 metadata->table = table; 215 215 216 216 return metadata; 217 217 } … … 224 224 psMetadataItem *value = NULL; 225 225 psMetadataType type = PS_META_ITEM_SET; 226 226 227 227 if ( md == NULL ) { 228 psError( __func__, "Null metadata collection not allowed" );229 return false;230 }231 228 psError( __func__, "Null metadata collection not allowed" ); 229 return false; 230 } 231 232 232 if ( metadataItem == NULL ) { 233 psError( __func__, "Null metadata item not allowed" );234 return false;235 }236 233 psError( __func__, "Null metadata item not allowed" ); 234 return false; 235 } 236 237 237 type = metadataItem->type; 238 238 239 239 mdTable = md->table; 240 240 if ( mdTable == NULL ) { 241 psError( __func__, "Null metadata table not allowed" );242 return false;243 }244 245 mdList = md->list; 246 if ( mdList == NULL ) { 247 psError( __func__, "Null metadata list not allowed" );248 return false;249 }250 241 psError( __func__, "Null metadata table not allowed" ); 242 return false; 243 } 244 245 mdList = md->list; 246 if ( mdList == NULL ) { 247 psError( __func__, "Null metadata list not allowed" ); 248 return false; 249 } 250 251 251 key = metadataItem->name; 252 252 if ( key == NULL ) { 253 psError( __func__, "Null key item not allowed" );254 return false;255 }256 253 psError( __func__, "Null key item not allowed" ); 254 return false; 255 } 256 257 257 // Check if key is already in table 258 258 value = ( psMetadataItem* ) psHashLookup( mdTable, key ); 259 259 if ( value != NULL && type != PS_META_ITEM_SET ) { 260 261 // The key was found and the new metadata item is a leaf node (its type isn't PS_META_ITEM_SET), so 262 // add the new metadata item to hash as a child of the existing metadata item folder node. 263 if ( !psListAdd( value->items, metadataItem, where ) ) { 264 psError( __func__, "Couldn't add metadata item to items list. Name: %s", 265 metadataItem->name ); 266 return false; 267 } 268 } else if ( value != NULL ) { 269 260 261 // The key was found and the new metadata item is a leaf node (its type isn't PS_META_ITEM_SET), so 262 // add the new metadata item to hash as a child of the existing metadata item folder node. 263 if ( !psListAdd( value->items, metadataItem, where ) ) { 264 psError( __func__, "Couldn't add metadata item to items list. Name: %s", 265 metadataItem->name ); 266 return false; 267 } 268 } else 269 if ( value != NULL ) { 270 270 271 // The key was found and the new metadata item is a folder node. Don't add new metadata item, since 271 272 // it will wipe out existing node. … … 274 275 return false; 275 276 } else { 276 277 277 278 // Duplicate key not found. Add new metadata item to metadata collection's hash 278 279 if ( !psHashAdd( mdTable, key, metadataItem ) ) { 279 psError( __func__, "Couldn't add metadata item to metadata collection table. Name: %s",280 metadataItem->name );281 return false;282 }283 } 284 280 psError( __func__, "Couldn't add metadata item to metadata collection table. Name: %s", 281 metadataItem->name ); 282 return false; 283 } 284 } 285 285 286 // Add all items to metadata collection's list, even if they have the same metadata item names 286 287 if ( !psListAdd( md->list, metadataItem, where ) ) { 287 psError( __func__, "Couldn't add metadata item to metadata collection list. Name: %s",288 metadataItem->name );289 return false;290 }291 288 psError( __func__, "Couldn't add metadata item to metadata collection list. Name: %s", 289 metadataItem->name ); 290 return false; 291 } 292 292 293 return true; 293 294 } … … 298 299 va_list argPtr; 299 300 psMetadataItem *metadataItem = NULL; 300 301 301 302 va_start( argPtr, comment ); 302 303 metadataItem = psMetadataItemAllocV( name, type, comment, argPtr ); 303 304 va_end( argPtr ); 304 305 305 306 if ( !psMetadataAddItem( md, where, metadataItem ) ) { 306 psError( __func__, "Couldn't add metadata item to metadata collection list. Name: %s",307 metadataItem->name );308 psFree( metadataItem );309 return false;310 }311 307 psError( __func__, "Couldn't add metadata item to metadata collection list. Name: %s", 308 metadataItem->name ); 309 psFree( metadataItem ); 310 return false; 311 } 312 312 313 // Decrement reference count, since the metadata item is now in metadata collection and no longer needed here 313 314 psMemDecrRefCounter( metadataItem ); 314 315 315 316 return true; 316 317 } … … 323 324 psMetadataItem *entry = NULL; 324 325 psMetadataItem *entryChild = NULL; 325 326 mdList = md->list; 327 if ( mdList == NULL ) { 328 psError( __func__, "Null metadata list not allowed" );329 return false;330 }331 326 327 mdList = md->list; 328 if ( mdList == NULL ) { 329 psError( __func__, "Null metadata list not allowed" ); 330 return false; 331 } 332 332 333 mdTable = md->table; 333 334 if ( mdTable == NULL ) { 334 psError( __func__, "Null metadata table not allowed" );335 return false;336 }337 335 psError( __func__, "Null metadata table not allowed" ); 336 return false; 337 } 338 338 339 // Select removal by key or index 339 340 if ( key != NULL ) { 340 341 // Remove by key name 342 entry = ( psMetadataItem* ) psHashLookup( mdTable, key ); 343 if ( entry == NULL ) { 344 psError( __func__, "Couldn't find metadata item remove. Name: %s", key ); 345 return false; 346 } 347 348 numChildren = entry->items->size; 349 if ( entry->type == PS_META_ITEM_SET && numChildren > 0 ) { 350 351 // Table entry has children. Entry and children must be removed from metadata collection's list 352 psListSetIterator( mdList, PS_LIST_HEAD ); 353 entryChild = psListGetCurrent( mdList ); 354 while ( entryChild != NULL ) { 355 if ( !psListRemove( entry->items, entryChild, PS_LIST_UNKNOWN ) ) { 356 psError( __func__, "Couldn't remove metadata item from list. Name: %s", key ); 357 return false; 358 } 359 entryChild = psListGetNext( entry->items ); 360 } 361 } 362 363 // Remove entry from metadata collection's list 364 if ( !psListRemove( mdList, entry, PS_LIST_UNKNOWN ) ) { 341 342 // Remove by key name 343 entry = ( psMetadataItem* ) psHashLookup( mdTable, key ); 344 if ( entry == NULL ) { 345 psError( __func__, "Couldn't find metadata item remove. Name: %s", key ); 346 return false; 347 } 348 349 numChildren = entry->items->size; 350 if ( entry->type == PS_META_ITEM_SET && numChildren > 0 ) { 351 352 // Table entry has children. Entry and children must be removed from metadata collection's list 353 psListSetIterator( mdList, PS_LIST_HEAD ); 354 entryChild = psListGetCurrent( mdList ); 355 while ( entryChild != NULL ) { 356 if ( !psListRemove( entry->items, entryChild, PS_LIST_UNKNOWN ) ) { 365 357 psError( __func__, "Couldn't remove metadata item from list. Name: %s", key ); 366 358 return false; 367 359 } 368 369 // Remove entry from metadata collection's table 370 if ( !psHashRemove( mdTable, key ) ) { 371 psError( __func__, "Couldn't remove metadata item from table. Name: %s", key ); 372 return false; 373 } 374 } else { 375 376 // Remove by index 377 entry = psListGet( mdList, where ); 378 if ( entry == NULL ) { 379 psError( __func__, "Couldn't find metadata item from list. Index: %d", where ); 380 return false; 381 } 382 383 key = entry->name; 384 if ( key == NULL ) { 385 psError( __func__, "Null key name not allowed. Index: %d", where ); 386 return false; 387 } 388 389 // Use recursive remove, now that key is known 390 psMetadataRemove( md, PS_LIST_UNKNOWN, key ); 391 } 392 360 entryChild = psListGetNext( entry->items ); 361 } 362 } 363 364 // Remove entry from metadata collection's list 365 if ( !psListRemove( mdList, entry, PS_LIST_UNKNOWN ) ) { 366 psError( __func__, "Couldn't remove metadata item from list. Name: %s", key ); 367 return false; 368 } 369 370 // Remove entry from metadata collection's table 371 if ( !psHashRemove( mdTable, key ) ) { 372 psError( __func__, "Couldn't remove metadata item from table. Name: %s", key ); 373 return false; 374 } 375 } else { 376 377 // Remove by index 378 entry = psListGet( mdList, where ); 379 if ( entry == NULL ) { 380 psError( __func__, "Couldn't find metadata item from list. Index: %d", where ); 381 return false; 382 } 383 384 key = entry->name; 385 if ( key == NULL ) { 386 psError( __func__, "Null key name not allowed. Index: %d", where ); 387 return false; 388 } 389 390 // Use recursive remove, now that key is known 391 psMetadataRemove( md, PS_LIST_UNKNOWN, key ); 392 } 393 393 394 return true; 394 395 } … … 398 399 psHash * mdTable = NULL; 399 400 psMetadataItem *entry = NULL; 400 401 401 402 mdTable = md->table; 402 403 if ( mdTable == NULL ) { 403 psError( __func__, "Null metadata table not allowed" );404 return NULL;405 }406 404 psError( __func__, "Null metadata table not allowed" ); 405 return NULL; 406 } 407 407 408 if ( key == NULL ) { 408 psError( __func__, "Null key name not allowed" );409 return NULL;410 }411 409 psError( __func__, "Null key name not allowed" ); 410 return NULL; 411 } 412 412 413 entry = ( psMetadataItem* ) psHashLookup( mdTable, key ); 413 414 if ( entry == NULL ) { 414 psError( __func__, "Could not find metadata item with given key. Key: %s", key );415 return NULL;416 }417 415 psError( __func__, "Could not find metadata item with given key. Key: %s", key ); 416 return NULL; 417 } 418 418 419 return entry; 419 420 } … … 423 424 psList * mdList = NULL; 424 425 psMetadataItem *entry = NULL; 425 426 mdList = md->list; 427 if ( mdList == NULL ) { 428 psError( __func__, "Null metadata list not allowed" );429 return NULL;430 }431 426 427 mdList = md->list; 428 if ( mdList == NULL ) { 429 psError( __func__, "Null metadata list not allowed" ); 430 return NULL; 431 } 432 432 433 entry = ( psMetadataItem* ) psListGet( mdList, where ); 433 434 if ( entry == NULL ) { 434 psError( __func__, "Couldn't find metadata item with given index. Index: %d", where );435 return NULL;436 }437 435 psError( __func__, "Couldn't find metadata item with given index. Index: %d", where ); 436 return NULL; 437 } 438 438 439 return entry; 439 440 } … … 442 443 { 443 444 psList * mdList = NULL; 444 445 mdList = md->list; 446 if ( mdList == NULL ) { 447 psError( __func__, "Null metadata list not allowed" );448 return false;449 }450 445 446 mdList = md->list; 447 if ( mdList == NULL ) { 448 psError( __func__, "Null metadata list not allowed" ); 449 return false; 450 } 451 451 452 psListSetIterator( mdList, where ); 452 453 453 454 return true; 454 455 } … … 458 459 psList * mdList = NULL; 459 460 psMetadataItem *entry = NULL; 460 461 mdList = md->list; 462 if ( mdList == NULL ) { 463 psError( __func__, "Null metadata list not allowed" );464 return NULL;465 }466 467 mdList = md->list; 468 if ( mdList == NULL ) { 469 psError( __func__, "Null metadata list not allowed" );470 return NULL;471 }472 461 462 mdList = md->list; 463 if ( mdList == NULL ) { 464 psError( __func__, "Null metadata list not allowed" ); 465 return NULL; 466 } 467 468 mdList = md->list; 469 if ( mdList == NULL ) { 470 psError( __func__, "Null metadata list not allowed" ); 471 return NULL; 472 } 473 473 474 psListSetIterator( mdList, which ); 474 475 entry = psListGetCurrent( mdList ); 475 476 while ( entry != NULL ) { 476 if ( !strncmp( match, entry->name, strlen( match ) ) ) {477 478 // Match found479 return entry;480 }481 entry = psListGetNext( mdList );482 }483 477 if ( !strncmp( match, entry->name, strlen( match ) ) ) { 478 479 // Match found 480 return entry; 481 } 482 entry = psListGetNext( mdList ); 483 } 484 484 485 // Match not found 485 486 if ( entry == NULL ) { 486 psError( __func__, "Couldn't find metadata item with given match. Match: %s", match );487 }488 487 psError( __func__, "Couldn't find metadata item with given match. Match: %s", match ); 488 } 489 489 490 return entry; 490 491 } … … 494 495 psList * mdList = NULL; 495 496 psMetadataItem *entry = NULL; 496 497 mdList = md->list; 498 if ( mdList == NULL ) { 499 psError( __func__, "Null metadata list not allowed" );500 return NULL;501 }502 503 mdList = md->list; 504 if ( mdList == NULL ) { 505 psError( __func__, "Null metadata list not allowed" );506 return NULL;507 }508 497 498 mdList = md->list; 499 if ( mdList == NULL ) { 500 psError( __func__, "Null metadata list not allowed" ); 501 return NULL; 502 } 503 504 mdList = md->list; 505 if ( mdList == NULL ) { 506 psError( __func__, "Null metadata list not allowed" ); 507 return NULL; 508 } 509 509 510 psListSetIterator( mdList, which ); 510 511 entry = psListGetCurrent( mdList ); 511 512 while ( entry != NULL ) { 512 if ( !strncmp( match, entry->name, strlen( match ) ) ) {513 514 // Match found515 return entry;516 }517 entry = psListGetPrevious( mdList );518 }519 513 if ( !strncmp( match, entry->name, strlen( match ) ) ) { 514 515 // Match found 516 return entry; 517 } 518 entry = psListGetPrevious( mdList ); 519 } 520 520 521 // Match not found 521 522 if ( entry == NULL ) { 522 psError( __func__, "Couldn't find metadata item with given match. Match: %s", match );523 }524 523 psError( __func__, "Couldn't find metadata item with given match. Match: %s", match ); 524 } 525 525 526 return entry; 526 527 } … … 529 530 { 530 531 psMetadataType type; 531 532 532 533 if ( fd == NULL ) { 533 psError( __func__, "Null file descriptor not allowed" );534 return ;535 }536 534 psError( __func__, "Null file descriptor not allowed" ); 535 return ; 536 } 537 537 538 if ( format == NULL ) { 538 psError( __func__, "Null format not allowed" );539 return ;540 }541 539 psError( __func__, "Null format not allowed" ); 540 return ; 541 } 542 542 543 if ( metadataItem == NULL ) { 543 psError( __func__, "Null metadata not allowed" );544 return ;545 }546 544 psError( __func__, "Null metadata not allowed" ); 545 return ; 546 } 547 547 548 type = metadataItem->type; 548 549 549 550 switch ( type ) { 550 case PS_META_BOOL:551 fprintf( fd, format, metadataItem->data.B );552 break;553 case PS_META_S32:554 fprintf( fd, format, metadataItem->data.S32 );555 break;556 case PS_META_F32:557 fprintf( fd, format, metadataItem->data.F32 );558 break;559 case PS_META_F64:560 fprintf( fd, format, metadataItem->data.F64 );561 break;562 case PS_META_STR:563 fprintf( fd, format, metadataItem->data.V );564 break;565 case PS_META_ITEM_SET:566 case PS_META_IMG:567 case PS_META_JPEG:568 case PS_META_PNG:569 case PS_META_ASTROM:570 case PS_META_UNKNOWN:571 default:572 psError( __func__, " Invalid psMetadataType to print: %d", type );573 }551 case PS_META_BOOL: 552 fprintf( fd, format, metadataItem->data.B ); 553 break; 554 case PS_META_S32: 555 fprintf( fd, format, metadataItem->data.S32 ); 556 break; 557 case PS_META_F32: 558 fprintf( fd, format, metadataItem->data.F32 ); 559 break; 560 case PS_META_F64: 561 fprintf( fd, format, metadataItem->data.F64 ); 562 break; 563 case PS_META_STR: 564 fprintf( fd, format, metadataItem->data.V ); 565 break; 566 case PS_META_ITEM_SET: 567 case PS_META_IMG: 568 case PS_META_JPEG: 569 case PS_META_PNG: 570 case PS_META_ASTROM: 571 case PS_META_UNKNOWN: 572 default: 573 psError( __func__, " Invalid psMetadataType to print: %d", type ); 574 } 574 575 } 575 576 … … 590 591 int keyNum = 0; 591 592 psMetadataType metadataItemType; 592 593 593 594 if ( fd == NULL ) { 594 psError( __func__, "Null FITS file descriptor not allowed" );595 return NULL;596 }597 595 psError( __func__, "Null FITS file descriptor not allowed" ); 596 return NULL; 597 } 598 598 599 if ( extname == NULL && extnum == 0 ) { 599 psError( __func__, "Null extname AND extnum = 0 not allowed" ); 600 return NULL; 601 } else if ( extname && extnum ) { 600 psError( __func__, "Null extname AND extnum = 0 not allowed" ); 601 return NULL; 602 } else 603 if ( extname && extnum ) { 602 604 psError( __func__, "Both extname AND extnum arguments should not have values." ); 603 605 return NULL; 604 606 } 605 607 606 608 // Allocate metadata if user didn't 607 609 if ( output == NULL ) { 608 output = psMetadataAlloc();609 }610 610 output = psMetadataAlloc(); 611 } 612 611 613 // Move to user designated HDU number or HDU name in FITS file. HDU numbers starts at one. 612 614 if ( extname == NULL ) { 613 if ( fits_movabs_hdu( fd, extnum, &hduType, &status ) != 0 ) { 614 fits_get_errstatus( status, fitsErr ); 615 psError( __func__, "FITS error while locating header: %s", fitsErr ); 616 status = 0; 617 return output; 618 } 619 } else if ( extnum > 0 ) { 615 if ( fits_movabs_hdu( fd, extnum, &hduType, &status ) != 0 ) { 616 fits_get_errstatus( status, fitsErr ); 617 psError( __func__, "FITS error while locating header: %s", fitsErr ); 618 status = 0; 619 return output; 620 } 621 } else 622 if ( extnum > 0 ) { 620 623 tempExtname = ( char* ) extname; 621 624 if ( fits_movnam_hdu( fd, ANY_HDU, tempExtname, 0, &status ) != 0 ) { 622 fits_get_errstatus( status, fitsErr );623 psError( __func__, "FITS error while locating header: %s", fitsErr );624 status = 0;625 return output;626 }627 } 628 625 fits_get_errstatus( status, fitsErr ); 626 psError( __func__, "FITS error while locating header: %s", fitsErr ); 627 status = 0; 628 return output; 629 } 630 } 631 629 632 // Get number of key names 630 633 if ( fits_get_hdrpos( fd, &numKeys, &keyNum, &status ) != 0 ) { 634 fits_get_errstatus( status, fitsErr ); 635 psError( __func__, "FITS error while reading keys: %s", fitsErr ); 636 status = 0; 637 return output; 638 } 639 640 // Get each key name. Keywords start at one. 641 for ( i = 1; i <= numKeys; i++ ) { 642 if ( fits_read_keyn( fd, i, keyName, keyValue, keyComment, &status ) != 0 ) { 631 643 fits_get_errstatus( status, fitsErr ); 632 psError( __func__, "FITS error while reading key s: %s", fitsErr );644 psError( __func__, "FITS error while reading key number %d: %s", i, fitsErr ); 633 645 status = 0; 634 646 return output; 635 647 } 636 637 // Get each key name. Keywords start at one. 638 for ( i = 1; i <= numKeys; i++ ) { 639 if ( fits_read_keyn( fd, i, keyName, keyValue, keyComment, &status ) != 0 ) { 640 fits_get_errstatus( status, fitsErr ); 641 psError( __func__, "FITS error while reading key number %d: %s", i, fitsErr ); 642 status = 0; 643 return output; 644 } 645 if ( fits_get_keytype( keyValue, &keyType, &status ) != 0 ) { 646 fits_get_errstatus( status, fitsErr ); 647 if ( status != VALUE_UNDEFINED ) { 648 psError( __func__, "FITS error while determining key type: %s", fitsErr ); 649 status = 0; 650 return output; 651 } else { 652 // Some keywords are still valid even though they don't have a type or value, like COMMENTS 653 keyType = 'C'; 654 status = 0; 655 } 656 } 657 658 switch ( keyType ) { 659 case 'I': 660 metadataItemType = PS_META_S32; 661 success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, atoi( keyValue ) ); 662 break; 663 case 'F': 664 metadataItemType = PS_META_F64; 665 success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, atof( keyValue ) ); 666 break; 667 case 'C': 668 metadataItemType = PS_META_STR; 669 success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, keyValue ); 670 break; 671 case 'L': 672 metadataItemType = PS_META_BOOL; 673 tempBool = ( keyValue[ 0 ] == 'T' ) ? 1 : 0; 674 success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, tempBool ); 675 break; 676 case 'U': 677 case 'X': 678 default: 679 psError( __func__, "Invalid psMetadataType: %c", keyType ); 680 return output; 681 } 682 683 if ( !success ) { 684 psError( __func__, "Failed to add metadata item. Name: %s", keyName ); 685 } 686 } 687 648 if ( fits_get_keytype( keyValue, &keyType, &status ) != 0 ) { 649 fits_get_errstatus( status, fitsErr ); 650 if ( status != VALUE_UNDEFINED ) { 651 psError( __func__, "FITS error while determining key type: %s", fitsErr ); 652 status = 0; 653 return output; 654 } else { 655 // Some keywords are still valid even though they don't have a type or value, like COMMENTS 656 keyType = 'C'; 657 status = 0; 658 } 659 } 660 661 switch ( keyType ) { 662 case 'I': 663 metadataItemType = PS_META_S32; 664 success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, atoi( keyValue ) ); 665 break; 666 case 'F': 667 metadataItemType = PS_META_F64; 668 success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, atof( keyValue ) ); 669 break; 670 case 'C': 671 metadataItemType = PS_META_STR; 672 success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, keyValue ); 673 break; 674 case 'L': 675 metadataItemType = PS_META_BOOL; 676 tempBool = ( keyValue[ 0 ] == 'T' ) ? 1 : 0; 677 success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, tempBool ); 678 break; 679 case 'U': 680 case 'X': 681 default: 682 psError( __func__, "Invalid psMetadataType: %c", keyType ); 683 return output; 684 } 685 686 if ( !success ) { 687 psError( __func__, "Failed to add metadata item. Name: %s", keyName ); 688 } 689 } 690 688 691 return output; 689 692 } -
trunk/psLib/src/astronomy/psMetadata.h
r1382 r1385 10 10 * @author Ross Harman, MHPCC 11 11 * 12 * @version $Revision: 1.1 1$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-08-04 2 2:11:09 $12 * @version $Revision: 1.12 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2004-08-04 23:37:39 $ 14 14 * 15 15 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 59 59 */ 60 60 typedef struct psMetadataItem 61 { 62 const int id; ///< Unique ID for metadata item. 63 char *restrict name; ///< Name of metadata item. 64 psMetadataType type; ///< Type of metadata item. 65 union 61 66 { 62 const int id; ///< Unique ID for metadata item. 63 char *restrict name; ///< Name of metadata item. 64 psMetadataType type; ///< Type of metadata item. 65 union 66 { 67 bool B; 68 psS32 S32; ///< Signed 32-bit integer data. 69 psF32 F32; ///< Single-precision float data. 70 psF64 F64; ///< Double-precision float data. 71 psPTR V; ///< Pointer to other type of data. 72 }data; ///< Union for data types. 73 char *comment; ///< Optional comment ("", not NULL). 74 psList *restrict items; ///< List of psMetadataItems with same name. 75 } 67 bool B; 68 psS32 S32; ///< Signed 32-bit integer data. 69 psF32 F32; ///< Single-precision float data. 70 psF64 F64; ///< Double-precision float data. 71 psPTR V; ///< Pointer to other type of data. 72 }data; ///< Union for data types. 73 char *comment; ///< Optional comment ("", not NULL). 74 psList *restrict items; ///< List of psMetadataItems with same name. 75 } 76 76 psMetadataItem; 77 77 … … 83 83 */ 84 84 typedef struct psMetadata 85 {86 psList* restrict list;87 psHash* restrict table;88 }85 { 86 psList* restrict list; 87 psHash* restrict table; 88 } 89 89 psMetadata; 90 90 -
trunk/psLib/src/astronomy/psPhotometry.h
r1384 r1385 9 9 * @author George Gusciora, MHPCC 10 10 * 11 * @version $Revision: 1. 3$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-08-04 23: 12:34$11 * @version $Revision: 1.4 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-08-04 23:37:39 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 39 39 * 40 40 */ 41 41 42 typedef struct 42 {43 const int ID; ///< ID number for this photometric system44 const char *name; ///< Name of photometric system45 const char *camera; ///< Camera for photometric system46 const char *filter; ///< Filter used for photometric system47 const char *detector; ///< Detector used for photometric system48 }43 { 44 const int ID; ///< ID number for this photometric system 45 const char *name; ///< Name of photometric system 46 const char *camera; ///< Camera for photometric system 47 const char *filter; ///< Filter used for photometric system 48 const char *detector; ///< Detector used for photometric system 49 } 49 50 psPhotSystem; 50 51 … … 54 55 * 55 56 */ 57 56 58 typedef struct 57 {58 psPhotSystem src; ///< Source photometric system59 psPhotSystem dst; ///< Destination photometric system60 psPhotSystem pP; ///< Primary color reference61 psPhotSystem pM; ///< Primary color reference62 psPhotSystem sP; ///< Secondary color reference63 psPhotSystem sM; ///< Secondary color reference64 float pA; ///< Color offset for references65 float sA; ///< Color offset for references66 psPolynomial3D transform; ///< Transformation from source to destination67 }59 { 60 psPhotSystem src; ///< Source photometric system 61 psPhotSystem dst; ///< Destination photometric system 62 psPhotSystem pP; ///< Primary color reference 63 psPhotSystem pM; ///< Primary color reference 64 psPhotSystem sP; ///< Secondary color reference 65 psPhotSystem sM; ///< Secondary color reference 66 float pA; ///< Color offset for references 67 float sA; ///< Color offset for references 68 psPolynomial3D transform; ///< Transformation from source to destination 69 } 68 70 psPhotTransform; 69 71 -
trunk/psLib/src/astronomy/psTime.c
r1272 r1385 12 12 * @author Ross Harman, MHPCC 13 13 * 14 * @version $Revision: 1.1 0$ $Name: not supported by cvs2svn $15 * @date $Date: 2004-0 7-22 21:24:54$14 * @version $Revision: 1.11 $ $Name: not supported by cvs2svn $ 15 * @date $Date: 2004-08-04 23:37:39 $ 16 16 * 17 17 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 100 100 static double leapseconds[NUM_LEAPSECOND_UPDATES][2] = 101 101 { 102 {2441317.5, 10.0}, 103 {2441499.5, 11.0}, 104 {2441683.5, 12.0}, 105 {2442048.5, 13.0}, 106 {2442413.5, 14.0}, 107 {2442778.5, 15.0}, 108 {2443144.5, 16.0}, 109 {2443509.5, 17.0}, 110 {2443874.5, 18.0}, 111 {2444239.5, 19.0}, 112 {2444786.5, 20.0}, 113 {2445151.5, 21.0}, 114 {2445516.5, 22.0}, 115 {2446247.5, 23.0}, 116 {2447161.5, 24.0}, 117 {2447892.5, 25.0}, 118 {2448257.5, 26.0}, 119 {2448804.5, 27.0}, 120 {2449169.5, 28.0}, 121 {2449534.5, 29.0}, 122 {2450083.5, 30.0}, 123 {2450630.5, 31.0}, 124 {2451179.5, 32.0} 102 { 103 2441317.5, 10.0 104 }, 105 { 106 2441499.5, 11.0 107 }, 108 { 109 2441683.5, 12.0 110 }, 111 { 112 2442048.5, 13.0 113 }, 114 { 115 2442413.5, 14.0 116 }, 117 { 118 2442778.5, 15.0 119 }, 120 { 121 2443144.5, 16.0 122 }, 123 { 124 2443509.5, 17.0 125 }, 126 { 127 2443874.5, 18.0 128 }, 129 { 130 2444239.5, 19.0 131 }, 132 { 133 2444786.5, 20.0 134 }, 135 { 136 2445151.5, 21.0 137 }, 138 { 139 2445516.5, 22.0 140 }, 141 { 142 2446247.5, 23.0 143 }, 144 { 145 2447161.5, 24.0 146 }, 147 { 148 2447892.5, 25.0 149 }, 150 { 151 2448257.5, 26.0 152 }, 153 { 154 2448804.5, 27.0 155 }, 156 { 157 2449169.5, 28.0 158 }, 159 { 160 2449534.5, 29.0 161 }, 162 { 163 2450083.5, 30.0 164 }, 165 { 166 2450630.5, 31.0 167 }, 168 { 169 2451179.5, 32.0 170 } 125 171 }; 126 172 … … 395 441 psError(__func__,"Null value for timeval arg not allowed"); 396 442 return outTime; 397 } else if(time->tv_sec < 0) 398 { 399 psError(__func__,"Negative seconds are not allowed: %ld", time->tv_sec); 400 return outTime; 401 } else if(time->tv_usec<0) 402 { 403 psError(__func__,"Negative microseconds are not allowed: %ld", time->tv_usec); 404 return outTime; 405 } 443 } else 444 if(time->tv_sec < 0) 445 { 446 psError(__func__,"Negative seconds are not allowed: %ld", time->tv_sec); 447 return outTime; 448 } else 449 if(time->tv_usec<0) 450 { 451 psError(__func__,"Negative microseconds are not allowed: %ld", time->tv_usec); 452 return outTime; 453 } 406 454 407 455 // Convert to psTime/TAI … … 420 468 int n; 421 469 int y; 422 int mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 470 int mon [] = 471 { 472 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 473 }; 423 474 long epoch; 424 475 psTime outTime; … … 433 484 psError(__func__,"Null value for tm arg not allowed"); 434 485 return outTime; 435 } else if(time->tm_year < 70) 436 { 437 psError(__func__,"Input times earlier than 1970 not allowed. Value: %d", time->tm_year+1900); 438 return outTime; 439 } else if(time->tm_mon<0 || time->tm_mon>11) 440 { 441 psError(__func__,"Month must have a value from 0 to 11. Value: %d", time->tm_mon); 442 return outTime; 443 } else if(time->tm_mday<1 || time->tm_mday>31) 444 { 445 psError(__func__,"Day must have a value from 1 to 31. Value: %d", time->tm_mday); 446 return outTime; 447 } else if(time->tm_hour<0 || time->tm_hour>23) 448 { 449 psError(__func__,"Hour must have a value from 0 to 23. Value: %d", time->tm_hour); 450 return outTime; 451 } else if(time->tm_min<0 || time->tm_min>59) 452 { 453 psError(__func__,"Minute must have a value from 0 to 59. Value: %d", time->tm_min); 454 return outTime; 455 } else if(time->tm_sec<0 || time->tm_sec>59) 456 { 457 psError(__func__,"Second must have a value from 0 to 59. Value: %d", time->tm_sec); 458 return outTime; 459 } 486 } else 487 if(time->tm_year < 70) 488 { 489 psError(__func__,"Input times earlier than 1970 not allowed. Value: %d", time->tm_year+1900); 490 return outTime; 491 } else 492 if(time->tm_mon<0 || time->tm_mon>11) 493 { 494 psError(__func__,"Month must have a value from 0 to 11. Value: %d", time->tm_mon); 495 return outTime; 496 } else 497 if(time->tm_mday<1 || time->tm_mday>31) 498 { 499 psError(__func__,"Day must have a value from 1 to 31. Value: %d", time->tm_mday); 500 return outTime; 501 } else 502 if(time->tm_hour<0 || time->tm_hour>23) 503 { 504 psError(__func__,"Hour must have a value from 0 to 23. Value: %d", time->tm_hour); 505 return outTime; 506 } else 507 if(time->tm_min<0 || time->tm_min>59) 508 { 509 psError(__func__,"Minute must have a value from 0 to 59. Value: %d", time->tm_min); 510 return outTime; 511 } else 512 if(time->tm_sec<0 || time->tm_sec>59) 513 { 514 psError(__func__,"Second must have a value from 0 to 59. Value: %d", time->tm_sec); 515 return outTime; 516 } 460 517 461 518 n = time->tm_year + 1900 - 1; -
trunk/psLib/src/astronomy/psTime.h
r1256 r1385 12 12 * @author Ross Harman, MHPCC 13 13 * 14 * @version $Revision: 1. 5$ $Name: not supported by cvs2svn $15 * @date $Date: 2004-0 7-22 01:03:00$14 * @version $Revision: 1.6 $ $Name: not supported by cvs2svn $ 15 * @date $Date: 2004-08-04 23:37:39 $ 16 16 * 17 17 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/collections/psArray.c
r1228 r1385 8 8 * @author Ross Harman, MHPCC 9 9 * 10 * @version $Revision: 1. 9$ $Name: not supported by cvs2svn $11 * @date $Date: 2004-0 7-15 22:18:02$10 * @version $Revision: 1.10 $ $Name: not supported by cvs2svn $ 11 * @date $Date: 2004-08-04 23:37:39 $ 12 12 * 13 13 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 67 67 psError(__func__, "Null input vector\n"); 68 68 return NULL; 69 } else if(in->nalloc != nalloc) { // No need to realloc to same size 70 if(nalloc < in->n) { 71 for (int i = nalloc; i < in->n; i++) { // For reduction in vector size 72 psFree(in->data[i]); 69 } else 70 if(in->nalloc != nalloc) { // No need to realloc to same size 71 if(nalloc < in->n) { 72 for (int i = nalloc; i < in->n; i++) { // For reduction in vector size 73 psFree(in->data[i]); 74 } 75 in->n = nalloc; 73 76 } 74 in->n = nalloc; 77 78 // Realloc after decrementation to avoid accessing freed array elements 79 in->data = psRealloc(in->data,nalloc*sizeof(psPTR)); 80 in->nalloc = nalloc; 75 81 } 76 77 // Realloc after decrementation to avoid accessing freed array elements78 in->data = psRealloc(in->data,nalloc*sizeof(psPTR));79 in->nalloc = nalloc;80 }81 82 82 83 return in; -
trunk/psLib/src/collections/psBitSet.c
r1172 r1385 10 10 * @author Ross Harman, MHPCC 11 11 * 12 * @version $Revision: 1.1 2$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-0 7-01 21:48:11$12 * @version $Revision: 1.13 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2004-08-04 23:37:39 $ 14 14 * 15 15 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 126 126 psError(__func__, " : Line %d - Null psBitSet for inBitSet argument", __LINE__); 127 127 return inBitSet; 128 } else if(bit < 0) { 129 psError(__func__, " : Line %d - Bit position too small: %d", __LINE__, bit); 130 return inBitSet; 131 } else if(bit > inBitSet->n*8-1) { 132 psError(__func__, " : Line %d - Bit position too large: %d", __LINE__, bit); 133 return inBitSet; 134 } 128 } else 129 if(bit < 0) { 130 psError(__func__, " : Line %d - Bit position too small: %d", __LINE__, bit); 131 return inBitSet; 132 } else 133 if(bit > inBitSet->n*8-1) { 134 psError(__func__, " : Line %d - Bit position too large: %d", __LINE__, bit); 135 return inBitSet; 136 } 135 137 136 138 // Variable byte is the byte in the array that contains the bit to be set … … 148 150 psError(__func__, " : Line %d - Null psBitSet for inBitSet argument", __LINE__); 149 151 return 0; 150 } else if(bit < 0) { 151 psError(__func__, " : Line %d - Bit position too small: %d", __LINE__, bit); 152 return 0; 153 } else if(bit > inBitSet->n*8-1) { 154 psError(__func__, " : Line %d - Bit position too large: %d", __LINE__, bit); 155 return 0; 156 } 152 } else 153 if(bit < 0) { 154 psError(__func__, " : Line %d - Bit position too small: %d", __LINE__, bit); 155 return 0; 156 } else 157 if(bit > inBitSet->n*8-1) { 158 psError(__func__, " : Line %d - Bit position too large: %d", __LINE__, bit); 159 return 0; 160 } 157 161 158 162 // Variable byte is the byte in the array that contains the bit to be tested -
trunk/psLib/src/collections/psList.c
r1228 r1385 6 6 * @author Robert Daniel DeSonia, MHPCC 7 7 * 8 * @version $Revision: 1.1 1$ $Name: not supported by cvs2svn $9 * @date $Date: 2004-0 7-15 22:18:02$8 * @version $Revision: 1.12 $ $Name: not supported by cvs2svn $ 9 * @date $Date: 2004-08-04 23:37:39 $ 10 10 * 11 11 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 349 349 if (list->iter == ITER_INIT_HEAD) { 350 350 return list->head; 351 } else if (list->iter == ITER_INIT_TAIL) { 352 return list->tail; 353 } else { 354 return list->iter; 355 } 351 } else 352 if (list->iter == ITER_INIT_TAIL) { 353 return list->tail; 354 } else { 355 return list->iter; 356 } 356 357 } 357 358 … … 360 361 if (list->iter == ITER_INIT_HEAD) { 361 362 return 0; 362 } else if (list->iter == ITER_INIT_TAIL) { 363 return list->size-1; 364 } else { 365 return list->iterIndex; 366 } 363 } else 364 if (list->iter == ITER_INIT_TAIL) { 365 return list->size-1; 366 } else { 367 return list->iterIndex; 368 } 367 369 } 368 370 -
trunk/psLib/src/collections/psMetadata.c
r1381 r1385 11 11 * @author Ross Harman, MHPCC 12 12 * 13 * @version $Revision: 1. 7$ $Name: not supported by cvs2svn $14 * @date $Date: 2004-08-04 2 1:05:24$13 * @version $Revision: 1.8 $ $Name: not supported by cvs2svn $ 14 * @date $Date: 2004-08-04 23:37:39 $ 15 15 * 16 16 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 65 65 { 66 66 psMetadataType type; 67 67 68 68 type = metadataItem->type; 69 69 70 70 if ( metadataItem == NULL ) { 71 return ;72 }73 71 return ; 72 } 73 74 74 psFree( metadataItem->name ); 75 75 psFree( metadataItem->comment ); 76 76 psFree( metadataItem->items ); 77 77 78 78 if ( type == PS_META_STR || 79 79 type == PS_META_IMG || … … 82 82 type == PS_META_ASTROM || 83 83 type == PS_META_UNKNOWN ) { 84 psFree( metadataItem->data.V );85 }84 psFree( metadataItem->data.V ); 85 } 86 86 } 87 87 … … 89 89 { 90 90 if ( metadata == NULL ) { 91 return ;92 }91 return ; 92 } 93 93 psFree( metadata->list ); 94 94 psFree( metadata->table ); … … 103 103 va_list argPtr; 104 104 psMetadataItem *metadataItem = NULL; 105 105 106 106 // Get the variable list parameters to pass to allocation function 107 107 va_start( argPtr, comment ); 108 108 109 109 // Call metadata item allocation 110 110 metadataItem = psMetadataItemAllocV( name, type, comment, argPtr ); 111 111 112 112 // Clean up stack after variable arguement has been used 113 113 va_end( argPtr ); 114 114 115 115 return metadataItem; 116 116 } … … 119 119 { 120 120 psMetadataItem * metadataItem = NULL; 121 121 122 122 if ( name == NULL ) { 123 psError( __func__, "Null value for string not allowed" );124 return NULL;125 }126 123 psError( __func__, "Null value for string not allowed" ); 124 return NULL; 125 } 126 127 127 // Allocate metadata item 128 128 metadataItem = ( psMetadataItem * ) psAlloc( sizeof( psMetadataItem ) ); 129 129 if ( metadataItem == NULL ) { 130 psAbort( __func__, "Failed to allocate memory" );131 }132 130 psAbort( __func__, "Failed to allocate memory" ); 131 } 132 133 133 // Set deallocator 134 134 p_psMemSetDeallocator( metadataItem, ( psFreeFcn ) metadataItemFree ); 135 135 136 136 // Allocate and set metadata item comment 137 137 metadataItem->comment = ( char * ) psAlloc( sizeof( char ) * MAX_STRING_LENGTH ); 138 138 if ( comment == NULL ) { 139 // Per SDRS, null isn't allowed, must use "" instead140 strncpy( metadataItem->comment, "", MAX_STRING_LENGTH );141 } else {142 strncpy( metadataItem->comment, comment, MAX_STRING_LENGTH );143 }144 139 // Per SDRS, null isn't allowed, must use "" instead 140 strncpy( metadataItem->comment, "", MAX_STRING_LENGTH ); 141 } else { 142 strncpy( metadataItem->comment, comment, MAX_STRING_LENGTH ); 143 } 144 145 145 // Set metadata item unique id 146 146 *( int* ) ( &metadataItem->id ) = ++metadataId; 147 147 148 148 // Set metadata item type 149 149 metadataItem->type = type; 150 150 151 151 // Set metadata item value 152 152 switch ( type ) { 153 case PS_META_BOOL:154 metadataItem->data.B = ( bool ) va_arg( argPtr, int );155 break;156 case PS_META_S32:157 metadataItem->data.S32 = va_arg( argPtr, psS32 );158 break;159 case PS_META_F32:160 metadataItem->data.F32 = ( psF32 ) va_arg( argPtr, psF64 );161 break;162 case PS_META_F64:163 metadataItem->data.F64 = va_arg( argPtr, psF64 );164 break;165 case PS_META_STR:166 metadataItem->data.V = psStringNCopy( va_arg( argPtr, char* ), MAX_STRING_LENGTH );167 break;168 case PS_META_IMG:169 case PS_META_JPEG:170 case PS_META_PNG:171 case PS_META_ASTROM:172 case PS_META_UNKNOWN:173 default:174 psError( __func__, "Invalid psMetadataType: %d", type );175 }176 153 case PS_META_BOOL: 154 metadataItem->data.B = ( bool ) va_arg( argPtr, int ); 155 break; 156 case PS_META_S32: 157 metadataItem->data.S32 = va_arg( argPtr, psS32 ); 158 break; 159 case PS_META_F32: 160 metadataItem->data.F32 = ( psF32 ) va_arg( argPtr, psF64 ); 161 break; 162 case PS_META_F64: 163 metadataItem->data.F64 = va_arg( argPtr, psF64 ); 164 break; 165 case PS_META_STR: 166 metadataItem->data.V = psStringNCopy( va_arg( argPtr, char* ), MAX_STRING_LENGTH ); 167 break; 168 case PS_META_IMG: 169 case PS_META_JPEG: 170 case PS_META_PNG: 171 case PS_META_ASTROM: 172 case PS_META_UNKNOWN: 173 default: 174 psError( __func__, "Invalid psMetadataType: %d", type ); 175 } 176 177 177 // Allocate and set metadata item name 178 178 metadataItem->name = ( char * ) psAlloc( sizeof( char ) * MAX_STRING_LENGTH ); 179 179 vsprintf( metadataItem->name, name, argPtr ); 180 180 181 181 // Allocate metadata items with same name. 182 182 metadataItem->items = psListAlloc( NULL ); 183 183 184 184 return metadataItem; 185 185 } … … 190 190 psHash *table = NULL; 191 191 psMetadata *metadata = NULL; 192 192 193 193 // Allocate metadata 194 194 metadata = ( psMetadata * ) psAlloc( sizeof( psMetadata ) ); 195 195 if ( metadata == NULL ) { 196 psAbort( __func__, "Failed to allocate metadata" );197 }198 196 psAbort( __func__, "Failed to allocate metadata" ); 197 } 198 199 199 // Set deallocator 200 200 p_psMemSetDeallocator( metadata, ( psFreeFcn ) metadataFree ); 201 201 202 202 // Allocate metadata's internal containers 203 203 list = ( psList * ) psListAlloc( NULL ); 204 204 if ( list == NULL ) { 205 psAbort( __func__, "Failed to allocate list" );206 }207 205 psAbort( __func__, "Failed to allocate list" ); 206 } 207 208 208 table = ( psHash * ) psHashAlloc( 10 ); 209 209 if ( table == NULL ) { 210 psAbort( __func__, "Failed to allocate table" );211 }212 210 psAbort( __func__, "Failed to allocate table" ); 211 } 212 213 213 metadata->list = list; 214 214 metadata->table = table; 215 215 216 216 return metadata; 217 217 } … … 224 224 psMetadataItem *value = NULL; 225 225 psMetadataType type = PS_META_ITEM_SET; 226 226 227 227 if ( md == NULL ) { 228 psError( __func__, "Null metadata collection not allowed" );229 return false;230 }231 228 psError( __func__, "Null metadata collection not allowed" ); 229 return false; 230 } 231 232 232 if ( metadataItem == NULL ) { 233 psError( __func__, "Null metadata item not allowed" );234 return false;235 }236 233 psError( __func__, "Null metadata item not allowed" ); 234 return false; 235 } 236 237 237 type = metadataItem->type; 238 238 239 239 mdTable = md->table; 240 240 if ( mdTable == NULL ) { 241 psError( __func__, "Null metadata table not allowed" );242 return false;243 }244 245 mdList = md->list; 246 if ( mdList == NULL ) { 247 psError( __func__, "Null metadata list not allowed" );248 return false;249 }250 241 psError( __func__, "Null metadata table not allowed" ); 242 return false; 243 } 244 245 mdList = md->list; 246 if ( mdList == NULL ) { 247 psError( __func__, "Null metadata list not allowed" ); 248 return false; 249 } 250 251 251 key = metadataItem->name; 252 252 if ( key == NULL ) { 253 psError( __func__, "Null key item not allowed" );254 return false;255 }256 253 psError( __func__, "Null key item not allowed" ); 254 return false; 255 } 256 257 257 // Check if key is already in table 258 258 value = ( psMetadataItem* ) psHashLookup( mdTable, key ); 259 259 if ( value != NULL && type != PS_META_ITEM_SET ) { 260 261 // The key was found and the new metadata item is a leaf node (its type isn't PS_META_ITEM_SET), so 262 // add the new metadata item to hash as a child of the existing metadata item folder node. 263 if ( !psListAdd( value->items, metadataItem, where ) ) { 264 psError( __func__, "Couldn't add metadata item to items list. Name: %s", 265 metadataItem->name ); 266 return false; 267 } 268 } else if ( value != NULL ) { 269 260 261 // The key was found and the new metadata item is a leaf node (its type isn't PS_META_ITEM_SET), so 262 // add the new metadata item to hash as a child of the existing metadata item folder node. 263 if ( !psListAdd( value->items, metadataItem, where ) ) { 264 psError( __func__, "Couldn't add metadata item to items list. Name: %s", 265 metadataItem->name ); 266 return false; 267 } 268 } else 269 if ( value != NULL ) { 270 270 271 // The key was found and the new metadata item is a folder node. Don't add new metadata item, since 271 272 // it will wipe out existing node. … … 274 275 return false; 275 276 } else { 276 277 277 278 // Duplicate key not found. Add new metadata item to metadata collection's hash 278 279 if ( !psHashAdd( mdTable, key, metadataItem ) ) { 279 psError( __func__, "Couldn't add metadata item to metadata collection table. Name: %s",280 metadataItem->name );281 return false;282 }283 } 284 280 psError( __func__, "Couldn't add metadata item to metadata collection table. Name: %s", 281 metadataItem->name ); 282 return false; 283 } 284 } 285 285 286 // Add all items to metadata collection's list, even if they have the same metadata item names 286 287 if ( !psListAdd( md->list, metadataItem, where ) ) { 287 psError( __func__, "Couldn't add metadata item to metadata collection list. Name: %s",288 metadataItem->name );289 return false;290 }291 288 psError( __func__, "Couldn't add metadata item to metadata collection list. Name: %s", 289 metadataItem->name ); 290 return false; 291 } 292 292 293 return true; 293 294 } … … 298 299 va_list argPtr; 299 300 psMetadataItem *metadataItem = NULL; 300 301 301 302 va_start( argPtr, comment ); 302 303 metadataItem = psMetadataItemAllocV( name, type, comment, argPtr ); 303 304 va_end( argPtr ); 304 305 305 306 if ( !psMetadataAddItem( md, where, metadataItem ) ) { 306 psError( __func__, "Couldn't add metadata item to metadata collection list. Name: %s",307 metadataItem->name );308 psFree( metadataItem );309 return false;310 }311 307 psError( __func__, "Couldn't add metadata item to metadata collection list. Name: %s", 308 metadataItem->name ); 309 psFree( metadataItem ); 310 return false; 311 } 312 312 313 // Decrement reference count, since the metadata item is now in metadata collection and no longer needed here 313 314 psMemDecrRefCounter( metadataItem ); 314 315 315 316 return true; 316 317 } … … 323 324 psMetadataItem *entry = NULL; 324 325 psMetadataItem *entryChild = NULL; 325 326 mdList = md->list; 327 if ( mdList == NULL ) { 328 psError( __func__, "Null metadata list not allowed" );329 return false;330 }331 326 327 mdList = md->list; 328 if ( mdList == NULL ) { 329 psError( __func__, "Null metadata list not allowed" ); 330 return false; 331 } 332 332 333 mdTable = md->table; 333 334 if ( mdTable == NULL ) { 334 psError( __func__, "Null metadata table not allowed" );335 return false;336 }337 335 psError( __func__, "Null metadata table not allowed" ); 336 return false; 337 } 338 338 339 // Select removal by key or index 339 340 if ( key != NULL ) { 340 341 // Remove by key name 342 entry = ( psMetadataItem* ) psHashLookup( mdTable, key ); 343 if ( entry == NULL ) { 344 psError( __func__, "Couldn't find metadata item remove. Name: %s", key ); 345 return false; 346 } 347 348 numChildren = entry->items->size; 349 if ( entry->type == PS_META_ITEM_SET && numChildren > 0 ) { 350 351 // Table entry has children. Entry and children must be removed from metadata collection's list 352 psListSetIterator( mdList, PS_LIST_HEAD ); 353 entryChild = psListGetCurrent( mdList ); 354 while ( entryChild != NULL ) { 355 if ( !psListRemove( entry->items, entryChild, PS_LIST_UNKNOWN ) ) { 356 psError( __func__, "Couldn't remove metadata item from list. Name: %s", key ); 357 return false; 358 } 359 entryChild = psListGetNext( entry->items ); 360 } 361 } 362 363 // Remove entry from metadata collection's list 364 if ( !psListRemove( mdList, entry, PS_LIST_UNKNOWN ) ) { 341 342 // Remove by key name 343 entry = ( psMetadataItem* ) psHashLookup( mdTable, key ); 344 if ( entry == NULL ) { 345 psError( __func__, "Couldn't find metadata item remove. Name: %s", key ); 346 return false; 347 } 348 349 numChildren = entry->items->size; 350 if ( entry->type == PS_META_ITEM_SET && numChildren > 0 ) { 351 352 // Table entry has children. Entry and children must be removed from metadata collection's list 353 psListSetIterator( mdList, PS_LIST_HEAD ); 354 entryChild = psListGetCurrent( mdList ); 355 while ( entryChild != NULL ) { 356 if ( !psListRemove( entry->items, entryChild, PS_LIST_UNKNOWN ) ) { 365 357 psError( __func__, "Couldn't remove metadata item from list. Name: %s", key ); 366 358 return false; 367 359 } 368 369 // Remove entry from metadata collection's table 370 if ( !psHashRemove( mdTable, key ) ) { 371 psError( __func__, "Couldn't remove metadata item from table. Name: %s", key ); 372 return false; 373 } 374 } else { 375 376 // Remove by index 377 entry = psListGet( mdList, where ); 378 if ( entry == NULL ) { 379 psError( __func__, "Couldn't find metadata item from list. Index: %d", where ); 380 return false; 381 } 382 383 key = entry->name; 384 if ( key == NULL ) { 385 psError( __func__, "Null key name not allowed. Index: %d", where ); 386 return false; 387 } 388 389 // Use recursive remove, now that key is known 390 psMetadataRemove( md, PS_LIST_UNKNOWN, key ); 391 } 392 360 entryChild = psListGetNext( entry->items ); 361 } 362 } 363 364 // Remove entry from metadata collection's list 365 if ( !psListRemove( mdList, entry, PS_LIST_UNKNOWN ) ) { 366 psError( __func__, "Couldn't remove metadata item from list. Name: %s", key ); 367 return false; 368 } 369 370 // Remove entry from metadata collection's table 371 if ( !psHashRemove( mdTable, key ) ) { 372 psError( __func__, "Couldn't remove metadata item from table. Name: %s", key ); 373 return false; 374 } 375 } else { 376 377 // Remove by index 378 entry = psListGet( mdList, where ); 379 if ( entry == NULL ) { 380 psError( __func__, "Couldn't find metadata item from list. Index: %d", where ); 381 return false; 382 } 383 384 key = entry->name; 385 if ( key == NULL ) { 386 psError( __func__, "Null key name not allowed. Index: %d", where ); 387 return false; 388 } 389 390 // Use recursive remove, now that key is known 391 psMetadataRemove( md, PS_LIST_UNKNOWN, key ); 392 } 393 393 394 return true; 394 395 } … … 398 399 psHash * mdTable = NULL; 399 400 psMetadataItem *entry = NULL; 400 401 401 402 mdTable = md->table; 402 403 if ( mdTable == NULL ) { 403 psError( __func__, "Null metadata table not allowed" );404 return NULL;405 }406 404 psError( __func__, "Null metadata table not allowed" ); 405 return NULL; 406 } 407 407 408 if ( key == NULL ) { 408 psError( __func__, "Null key name not allowed" );409 return NULL;410 }411 409 psError( __func__, "Null key name not allowed" ); 410 return NULL; 411 } 412 412 413 entry = ( psMetadataItem* ) psHashLookup( mdTable, key ); 413 414 if ( entry == NULL ) { 414 psError( __func__, "Could not find metadata item with given key. Key: %s", key );415 return NULL;416 }417 415 psError( __func__, "Could not find metadata item with given key. Key: %s", key ); 416 return NULL; 417 } 418 418 419 return entry; 419 420 } … … 423 424 psList * mdList = NULL; 424 425 psMetadataItem *entry = NULL; 425 426 mdList = md->list; 427 if ( mdList == NULL ) { 428 psError( __func__, "Null metadata list not allowed" );429 return NULL;430 }431 426 427 mdList = md->list; 428 if ( mdList == NULL ) { 429 psError( __func__, "Null metadata list not allowed" ); 430 return NULL; 431 } 432 432 433 entry = ( psMetadataItem* ) psListGet( mdList, where ); 433 434 if ( entry == NULL ) { 434 psError( __func__, "Couldn't find metadata item with given index. Index: %d", where );435 return NULL;436 }437 435 psError( __func__, "Couldn't find metadata item with given index. Index: %d", where ); 436 return NULL; 437 } 438 438 439 return entry; 439 440 } … … 442 443 { 443 444 psList * mdList = NULL; 444 445 mdList = md->list; 446 if ( mdList == NULL ) { 447 psError( __func__, "Null metadata list not allowed" );448 return false;449 }450 445 446 mdList = md->list; 447 if ( mdList == NULL ) { 448 psError( __func__, "Null metadata list not allowed" ); 449 return false; 450 } 451 451 452 psListSetIterator( mdList, where ); 452 453 453 454 return true; 454 455 } … … 458 459 psList * mdList = NULL; 459 460 psMetadataItem *entry = NULL; 460 461 mdList = md->list; 462 if ( mdList == NULL ) { 463 psError( __func__, "Null metadata list not allowed" );464 return NULL;465 }466 467 mdList = md->list; 468 if ( mdList == NULL ) { 469 psError( __func__, "Null metadata list not allowed" );470 return NULL;471 }472 461 462 mdList = md->list; 463 if ( mdList == NULL ) { 464 psError( __func__, "Null metadata list not allowed" ); 465 return NULL; 466 } 467 468 mdList = md->list; 469 if ( mdList == NULL ) { 470 psError( __func__, "Null metadata list not allowed" ); 471 return NULL; 472 } 473 473 474 psListSetIterator( mdList, which ); 474 475 entry = psListGetCurrent( mdList ); 475 476 while ( entry != NULL ) { 476 if ( !strncmp( match, entry->name, strlen( match ) ) ) {477 478 // Match found479 return entry;480 }481 entry = psListGetNext( mdList );482 }483 477 if ( !strncmp( match, entry->name, strlen( match ) ) ) { 478 479 // Match found 480 return entry; 481 } 482 entry = psListGetNext( mdList ); 483 } 484 484 485 // Match not found 485 486 if ( entry == NULL ) { 486 psError( __func__, "Couldn't find metadata item with given match. Match: %s", match );487 }488 487 psError( __func__, "Couldn't find metadata item with given match. Match: %s", match ); 488 } 489 489 490 return entry; 490 491 } … … 494 495 psList * mdList = NULL; 495 496 psMetadataItem *entry = NULL; 496 497 mdList = md->list; 498 if ( mdList == NULL ) { 499 psError( __func__, "Null metadata list not allowed" );500 return NULL;501 }502 503 mdList = md->list; 504 if ( mdList == NULL ) { 505 psError( __func__, "Null metadata list not allowed" );506 return NULL;507 }508 497 498 mdList = md->list; 499 if ( mdList == NULL ) { 500 psError( __func__, "Null metadata list not allowed" ); 501 return NULL; 502 } 503 504 mdList = md->list; 505 if ( mdList == NULL ) { 506 psError( __func__, "Null metadata list not allowed" ); 507 return NULL; 508 } 509 509 510 psListSetIterator( mdList, which ); 510 511 entry = psListGetCurrent( mdList ); 511 512 while ( entry != NULL ) { 512 if ( !strncmp( match, entry->name, strlen( match ) ) ) {513 514 // Match found515 return entry;516 }517 entry = psListGetPrevious( mdList );518 }519 513 if ( !strncmp( match, entry->name, strlen( match ) ) ) { 514 515 // Match found 516 return entry; 517 } 518 entry = psListGetPrevious( mdList ); 519 } 520 520 521 // Match not found 521 522 if ( entry == NULL ) { 522 psError( __func__, "Couldn't find metadata item with given match. Match: %s", match );523 }524 523 psError( __func__, "Couldn't find metadata item with given match. Match: %s", match ); 524 } 525 525 526 return entry; 526 527 } … … 529 530 { 530 531 psMetadataType type; 531 532 532 533 if ( fd == NULL ) { 533 psError( __func__, "Null file descriptor not allowed" );534 return ;535 }536 534 psError( __func__, "Null file descriptor not allowed" ); 535 return ; 536 } 537 537 538 if ( format == NULL ) { 538 psError( __func__, "Null format not allowed" );539 return ;540 }541 539 psError( __func__, "Null format not allowed" ); 540 return ; 541 } 542 542 543 if ( metadataItem == NULL ) { 543 psError( __func__, "Null metadata not allowed" );544 return ;545 }546 544 psError( __func__, "Null metadata not allowed" ); 545 return ; 546 } 547 547 548 type = metadataItem->type; 548 549 549 550 switch ( type ) { 550 case PS_META_BOOL:551 fprintf( fd, format, metadataItem->data.B );552 break;553 case PS_META_S32:554 fprintf( fd, format, metadataItem->data.S32 );555 break;556 case PS_META_F32:557 fprintf( fd, format, metadataItem->data.F32 );558 break;559 case PS_META_F64:560 fprintf( fd, format, metadataItem->data.F64 );561 break;562 case PS_META_STR:563 fprintf( fd, format, metadataItem->data.V );564 break;565 case PS_META_ITEM_SET:566 case PS_META_IMG:567 case PS_META_JPEG:568 case PS_META_PNG:569 case PS_META_ASTROM:570 case PS_META_UNKNOWN:571 default:572 psError( __func__, " Invalid psMetadataType to print: %d", type );573 }551 case PS_META_BOOL: 552 fprintf( fd, format, metadataItem->data.B ); 553 break; 554 case PS_META_S32: 555 fprintf( fd, format, metadataItem->data.S32 ); 556 break; 557 case PS_META_F32: 558 fprintf( fd, format, metadataItem->data.F32 ); 559 break; 560 case PS_META_F64: 561 fprintf( fd, format, metadataItem->data.F64 ); 562 break; 563 case PS_META_STR: 564 fprintf( fd, format, metadataItem->data.V ); 565 break; 566 case PS_META_ITEM_SET: 567 case PS_META_IMG: 568 case PS_META_JPEG: 569 case PS_META_PNG: 570 case PS_META_ASTROM: 571 case PS_META_UNKNOWN: 572 default: 573 psError( __func__, " Invalid psMetadataType to print: %d", type ); 574 } 574 575 } 575 576 … … 590 591 int keyNum = 0; 591 592 psMetadataType metadataItemType; 592 593 593 594 if ( fd == NULL ) { 594 psError( __func__, "Null FITS file descriptor not allowed" );595 return NULL;596 }597 595 psError( __func__, "Null FITS file descriptor not allowed" ); 596 return NULL; 597 } 598 598 599 if ( extname == NULL && extnum == 0 ) { 599 psError( __func__, "Null extname AND extnum = 0 not allowed" ); 600 return NULL; 601 } else if ( extname && extnum ) { 600 psError( __func__, "Null extname AND extnum = 0 not allowed" ); 601 return NULL; 602 } else 603 if ( extname && extnum ) { 602 604 psError( __func__, "Both extname AND extnum arguments should not have values." ); 603 605 return NULL; 604 606 } 605 607 606 608 // Allocate metadata if user didn't 607 609 if ( output == NULL ) { 608 output = psMetadataAlloc();609 }610 610 output = psMetadataAlloc(); 611 } 612 611 613 // Move to user designated HDU number or HDU name in FITS file. HDU numbers starts at one. 612 614 if ( extname == NULL ) { 613 if ( fits_movabs_hdu( fd, extnum, &hduType, &status ) != 0 ) { 614 fits_get_errstatus( status, fitsErr ); 615 psError( __func__, "FITS error while locating header: %s", fitsErr ); 616 status = 0; 617 return output; 618 } 619 } else if ( extnum > 0 ) { 615 if ( fits_movabs_hdu( fd, extnum, &hduType, &status ) != 0 ) { 616 fits_get_errstatus( status, fitsErr ); 617 psError( __func__, "FITS error while locating header: %s", fitsErr ); 618 status = 0; 619 return output; 620 } 621 } else 622 if ( extnum > 0 ) { 620 623 tempExtname = ( char* ) extname; 621 624 if ( fits_movnam_hdu( fd, ANY_HDU, tempExtname, 0, &status ) != 0 ) { 622 fits_get_errstatus( status, fitsErr );623 psError( __func__, "FITS error while locating header: %s", fitsErr );624 status = 0;625 return output;626 }627 } 628 625 fits_get_errstatus( status, fitsErr ); 626 psError( __func__, "FITS error while locating header: %s", fitsErr ); 627 status = 0; 628 return output; 629 } 630 } 631 629 632 // Get number of key names 630 633 if ( fits_get_hdrpos( fd, &numKeys, &keyNum, &status ) != 0 ) { 634 fits_get_errstatus( status, fitsErr ); 635 psError( __func__, "FITS error while reading keys: %s", fitsErr ); 636 status = 0; 637 return output; 638 } 639 640 // Get each key name. Keywords start at one. 641 for ( i = 1; i <= numKeys; i++ ) { 642 if ( fits_read_keyn( fd, i, keyName, keyValue, keyComment, &status ) != 0 ) { 631 643 fits_get_errstatus( status, fitsErr ); 632 psError( __func__, "FITS error while reading key s: %s", fitsErr );644 psError( __func__, "FITS error while reading key number %d: %s", i, fitsErr ); 633 645 status = 0; 634 646 return output; 635 647 } 636 637 // Get each key name. Keywords start at one. 638 for ( i = 1; i <= numKeys; i++ ) { 639 if ( fits_read_keyn( fd, i, keyName, keyValue, keyComment, &status ) != 0 ) { 640 fits_get_errstatus( status, fitsErr ); 641 psError( __func__, "FITS error while reading key number %d: %s", i, fitsErr ); 642 status = 0; 643 return output; 644 } 645 if ( fits_get_keytype( keyValue, &keyType, &status ) != 0 ) { 646 fits_get_errstatus( status, fitsErr ); 647 if ( status != VALUE_UNDEFINED ) { 648 psError( __func__, "FITS error while determining key type: %s", fitsErr ); 649 status = 0; 650 return output; 651 } else { 652 // Some keywords are still valid even though they don't have a type or value, like COMMENTS 653 keyType = 'C'; 654 status = 0; 655 } 656 } 657 658 switch ( keyType ) { 659 case 'I': 660 metadataItemType = PS_META_S32; 661 success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, atoi( keyValue ) ); 662 break; 663 case 'F': 664 metadataItemType = PS_META_F64; 665 success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, atof( keyValue ) ); 666 break; 667 case 'C': 668 metadataItemType = PS_META_STR; 669 success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, keyValue ); 670 break; 671 case 'L': 672 metadataItemType = PS_META_BOOL; 673 tempBool = ( keyValue[ 0 ] == 'T' ) ? 1 : 0; 674 success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, tempBool ); 675 break; 676 case 'U': 677 case 'X': 678 default: 679 psError( __func__, "Invalid psMetadataType: %c", keyType ); 680 return output; 681 } 682 683 if ( !success ) { 684 psError( __func__, "Failed to add metadata item. Name: %s", keyName ); 685 } 686 } 687 648 if ( fits_get_keytype( keyValue, &keyType, &status ) != 0 ) { 649 fits_get_errstatus( status, fitsErr ); 650 if ( status != VALUE_UNDEFINED ) { 651 psError( __func__, "FITS error while determining key type: %s", fitsErr ); 652 status = 0; 653 return output; 654 } else { 655 // Some keywords are still valid even though they don't have a type or value, like COMMENTS 656 keyType = 'C'; 657 status = 0; 658 } 659 } 660 661 switch ( keyType ) { 662 case 'I': 663 metadataItemType = PS_META_S32; 664 success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, atoi( keyValue ) ); 665 break; 666 case 'F': 667 metadataItemType = PS_META_F64; 668 success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, atof( keyValue ) ); 669 break; 670 case 'C': 671 metadataItemType = PS_META_STR; 672 success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, keyValue ); 673 break; 674 case 'L': 675 metadataItemType = PS_META_BOOL; 676 tempBool = ( keyValue[ 0 ] == 'T' ) ? 1 : 0; 677 success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, tempBool ); 678 break; 679 case 'U': 680 case 'X': 681 default: 682 psError( __func__, "Invalid psMetadataType: %c", keyType ); 683 return output; 684 } 685 686 if ( !success ) { 687 psError( __func__, "Failed to add metadata item. Name: %s", keyName ); 688 } 689 } 690 688 691 return output; 689 692 } -
trunk/psLib/src/collections/psMetadata.h
r1382 r1385 10 10 * @author Ross Harman, MHPCC 11 11 * 12 * @version $Revision: 1.1 1$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-08-04 2 2:11:09 $12 * @version $Revision: 1.12 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2004-08-04 23:37:39 $ 14 14 * 15 15 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 59 59 */ 60 60 typedef struct psMetadataItem 61 { 62 const int id; ///< Unique ID for metadata item. 63 char *restrict name; ///< Name of metadata item. 64 psMetadataType type; ///< Type of metadata item. 65 union 61 66 { 62 const int id; ///< Unique ID for metadata item. 63 char *restrict name; ///< Name of metadata item. 64 psMetadataType type; ///< Type of metadata item. 65 union 66 { 67 bool B; 68 psS32 S32; ///< Signed 32-bit integer data. 69 psF32 F32; ///< Single-precision float data. 70 psF64 F64; ///< Double-precision float data. 71 psPTR V; ///< Pointer to other type of data. 72 }data; ///< Union for data types. 73 char *comment; ///< Optional comment ("", not NULL). 74 psList *restrict items; ///< List of psMetadataItems with same name. 75 } 67 bool B; 68 psS32 S32; ///< Signed 32-bit integer data. 69 psF32 F32; ///< Single-precision float data. 70 psF64 F64; ///< Double-precision float data. 71 psPTR V; ///< Pointer to other type of data. 72 }data; ///< Union for data types. 73 char *comment; ///< Optional comment ("", not NULL). 74 psList *restrict items; ///< List of psMetadataItems with same name. 75 } 76 76 psMetadataItem; 77 77 … … 83 83 */ 84 84 typedef struct psMetadata 85 {86 psList* restrict list;87 psHash* restrict table;88 }85 { 86 psList* restrict list; 87 psHash* restrict table; 88 } 89 89 psMetadata; 90 90 -
trunk/psLib/src/collections/psScalar.c
r1162 r1385 8 8 * @author Ross Harman, MHPCC 9 9 * 10 * @version $Revision: 1. 3$ $Name: not supported by cvs2svn $11 * @date $Date: 2004-0 7-01 00:14:40$10 * @version $Revision: 1.4 $ $Name: not supported by cvs2svn $ 11 * @date $Date: 2004-08-04 23:37:39 $ 12 12 * 13 13 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/collections/psScalar.h
r1060 r1385 10 10 * @author Ross Harman, MHPCC 11 11 * 12 * @version $Revision: 1. 1$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-0 6-18 23:36:02$12 * @version $Revision: 1.2 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2004-08-04 23:37:39 $ 14 14 * 15 15 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/collections/psVector.c
r1360 r1385 8 8 * @author Ross Harman, MHPCC 9 9 * 10 * @version $Revision: 1.1 7$ $Name: not supported by cvs2svn $11 * @date $Date: 2004-0 7-31 02:28:10$10 * @version $Revision: 1.18 $ $Name: not supported by cvs2svn $ 11 * @date $Date: 2004-08-04 23:37:39 $ 12 12 * 13 13 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 63 63 psVector * psVec = NULL; 64 64 int elementSize = 0; 65 65 66 66 // Invalid nalloc 67 67 if ( nalloc < 1 ) { 68 psError( __func__, "Invalid value for nalloc. nalloc: %d\n", nalloc );69 return NULL;70 }71 68 psError( __func__, "Invalid value for nalloc. nalloc: %d\n", nalloc ); 69 return NULL; 70 } 71 72 72 elementSize = PSELEMTYPE_SIZEOF( elemType ); 73 73 74 74 // Create vector struct 75 75 psVec = ( psVector * ) psAlloc( sizeof( psVector ) ); 76 76 p_psMemSetDeallocator( psVec, ( psFreeFcn ) vectorFree ); 77 77 78 78 psVec->type.dimen = PS_DIMEN_VECTOR; 79 79 psVec->type.type = elemType; 80 80 psVec->nalloc = nalloc; 81 81 psVec->n = nalloc; 82 82 83 83 // Create vector data array 84 84 psVec->data.V = psAlloc( nalloc * elementSize ); 85 85 86 86 return psVec; 87 87 } … … 91 91 int elementSize = 0; 92 92 psElemType elemType; 93 93 94 94 // Invalid nalloc 95 95 if ( nalloc < 1 ) { 96 psError( __func__, "Invalid value for realloc (%d)\n", nalloc );97 return NULL;98 }99 96 psError( __func__, "Invalid value for realloc (%d)\n", nalloc ); 97 return NULL; 98 } 99 100 100 if ( in == NULL ) { 101 psError( __func__, "Null input vector\n" ); 102 return NULL; 103 } else if ( in->nalloc != nalloc ) { // No need to realloc to same size 101 psError( __func__, "Null input vector\n" ); 102 return NULL; 103 } else 104 if ( in->nalloc != nalloc ) { // No need to realloc to same size 104 105 elemType = in->type.type; 105 106 elementSize = PSELEMTYPE_SIZEOF( elemType ); 106 107 if ( nalloc < in->n ) { 107 in->n = nalloc;108 }109 108 in->n = nalloc; 109 } 110 110 111 // Realloc after decrementation to avoid accessing freed array elements 111 112 in->data.V = psRealloc( in->data.V, nalloc * elementSize ); 112 113 in->nalloc = nalloc; 113 114 } 114 115 115 116 return in; 116 117 } … … 119 120 { 120 121 psElemType elemType; 121 122 122 123 if ( in == NULL ) { 123 return psVectorAlloc( nalloc, type );124 }125 124 return psVectorAlloc( nalloc, type ); 125 } 126 126 127 elemType = in->type.type; 127 128 128 129 if ( in->nalloc == nalloc && elemType == type ) { 129 // it is proper size/type already130 return in;131 }132 130 // it is proper size/type already 131 return in; 132 } 133 133 134 // Invalid nalloc 134 135 if ( nalloc < 1 ) { 135 psError( __func__, "Invalid value for nalloc (%d)\n", nalloc );136 psFree( in );137 return NULL;138 }139 140 136 psError( __func__, "Invalid value for nalloc (%d)\n", nalloc ); 137 psFree( in ); 138 return NULL; 139 } 140 141 141 142 in->data.V = psRealloc( in->data.V, nalloc * PSELEMTYPE_SIZEOF( type ) ); 142 143 143 144 in->type.type = type; 144 145 in->nalloc = nalloc; 145 146 in->n = nalloc; 146 147 147 148 return in; 148 149 } … … 156 157 void *outVec = NULL; 157 158 psElemType inType = 0; 158 159 159 160 if ( inVector == NULL ) { 160 psError( __func__, " : Line %d - Null input vector\n", __LINE__ );161 return outVector;162 }163 161 psError( __func__, " : Line %d - Null input vector\n", __LINE__ ); 162 return outVector; 163 } 164 164 165 inType = inVector->type.type; 165 166 inN = inVector->n; 166 167 inVec = inVector->data.V; 167 168 elSize = PSELEMTYPE_SIZEOF( inType ); 168 169 169 170 if ( outVector == NULL ) { 170 outVector = psVectorAlloc( inN, inType );171 outVector->n = inVector->n;172 }173 171 outVector = psVectorAlloc( inN, inType ); 172 outVector->n = inVector->n; 173 } 174 174 175 outN = outVector->n; 175 176 outVec = outVector->data.V; 176 177 177 178 if ( inN != outN ) { 178 psError( __func__, " : Line %d - Input and output vector sizes are not equal: in=%d out=%d\n", __LINE__,179 inN, outN );180 return outVector;181 }182 179 psError( __func__, " : Line %d - Input and output vector sizes are not equal: in=%d out=%d\n", __LINE__, 180 inN, outN ); 181 return outVector; 182 } 183 183 184 if ( inType != outVector->type.type ) { 184 psError( __func__, " : Line %d - Input and output vectors are not same type: in=%d out=%d\n", __LINE__,185 inType, outVector->type.type );186 return outVector;187 }188 185 psError( __func__, " : Line %d - Input and output vectors are not same type: in=%d out=%d\n", __LINE__, 186 inType, outVector->type.type ); 187 return outVector; 188 } 189 189 190 if ( inN == 0 ) { 190 psError( __func__, " : Line %d - No elements in use for input vector\n", __LINE__ );191 return outVector;192 }193 191 psError( __func__, " : Line %d - No elements in use for input vector\n", __LINE__ ); 192 return outVector; 193 } 194 194 195 if ( outN == 0 ) { 195 psError( __func__, " : Line %d - No elements in use for output vector\n", __LINE__ );196 return outVector;197 }198 196 psError( __func__, " : Line %d - No elements in use for output vector\n", __LINE__ ); 197 return outVector; 198 } 199 199 200 // Copy input vector values into output vector 200 201 memcpy( outVec, inVec, elSize * outN ); 201 202 202 203 // Sort output vector 203 204 switch ( inType ) { 204 case PS_TYPE_U8:205 qsort( outVec, inN, elSize, psCompareU8 );206 break;207 case PS_TYPE_U16:208 qsort( outVec, inN, elSize, psCompareU16 );209 break;210 case PS_TYPE_U32:211 qsort( outVec, inN, elSize, psCompareU32 );212 break;213 case PS_TYPE_U64:214 qsort( outVec, inN, elSize, psCompareU64 );215 break;216 case PS_TYPE_S8:217 qsort( outVec, inN, elSize, psCompareS8 );218 break;219 case PS_TYPE_S16:220 qsort( outVec, inN, elSize, psCompareS16 );221 break;222 case PS_TYPE_S32:223 qsort( outVec, inN, elSize, psCompareS32 );224 break;225 case PS_TYPE_S64:226 qsort( outVec, inN, elSize, psCompareS64 );227 break;228 case PS_TYPE_F32:229 qsort( outVec, inN, elSize, psCompareF32 );230 break;231 case PS_TYPE_F64:232 qsort( outVec, inN, elSize, psCompareF64 );233 break;234 default:235 psError( __func__, " : Line %d - Invalid psType\n", __LINE__ );236 }237 205 case PS_TYPE_U8: 206 qsort( outVec, inN, elSize, psCompareU8 ); 207 break; 208 case PS_TYPE_U16: 209 qsort( outVec, inN, elSize, psCompareU16 ); 210 break; 211 case PS_TYPE_U32: 212 qsort( outVec, inN, elSize, psCompareU32 ); 213 break; 214 case PS_TYPE_U64: 215 qsort( outVec, inN, elSize, psCompareU64 ); 216 break; 217 case PS_TYPE_S8: 218 qsort( outVec, inN, elSize, psCompareS8 ); 219 break; 220 case PS_TYPE_S16: 221 qsort( outVec, inN, elSize, psCompareS16 ); 222 break; 223 case PS_TYPE_S32: 224 qsort( outVec, inN, elSize, psCompareS32 ); 225 break; 226 case PS_TYPE_S64: 227 qsort( outVec, inN, elSize, psCompareS64 ); 228 break; 229 case PS_TYPE_F32: 230 qsort( outVec, inN, elSize, psCompareF32 ); 231 break; 232 case PS_TYPE_F64: 233 qsort( outVec, inN, elSize, psCompareF64 ); 234 break; 235 default: 236 psError( __func__, " : Line %d - Invalid psType\n", __LINE__ ); 237 } 238 238 239 return outVector; 239 240 } … … 241 242 #define SORT_INDICES(TYPE) \ 242 243 for(i=0; i<inN; i++) { \ 243 for(j=0; j<inN; j++) { \244 diff = fabs((double)tmpVector->data.TYPE[i] - inVec[j]); \245 if(diff < FLT_EPSILON) { \246 outVec[i] = j; \247 break; \248 } \249 } \250 }251 244 for(j=0; j<inN; j++) { \ 245 diff = fabs((double)tmpVector->data.TYPE[i] - inVec[j]); \ 246 if(diff < FLT_EPSILON) { \ 247 outVec[i] = j; \ 248 break; \ 249 } \ 250 } \ 251 } 252 252 253 psVector *psVectorSortIndex( psVector *restrict outVector, const psVector *restrict inVector ) 253 254 { … … 261 262 psVector *tmpVector = NULL; 262 263 psElemType inType = 0; 263 264 264 265 if ( inVector == NULL ) { 265 psError( __func__, " : Line %d - Null input vector\n", __LINE__ );266 return outVector;267 }268 266 psError( __func__, " : Line %d - Null input vector\n", __LINE__ ); 267 return outVector; 268 } 269 269 270 inN = inVector->n; 270 271 inVec = inVector->data.V; 271 272 inType = inVector->type.type; 272 273 273 274 if ( outVector == NULL ) { 274 outVector = psVectorAlloc( inN, PS_TYPE_U32 );275 outVector->n = inN;276 }277 275 outVector = psVectorAlloc( inN, PS_TYPE_U32 ); 276 outVector->n = inN; 277 } 278 278 279 outN = outVector->n; 279 280 outVec = outVector->data.V; 280 281 281 282 if ( inN != outN ) { 282 psError( __func__, " : Line %d - Input and output vector sizes are not equal: in=%d out=%d\n",283 __LINE__, inN, outN );284 return outVector;285 }286 283 psError( __func__, " : Line %d - Input and output vector sizes are not equal: in=%d out=%d\n", 284 __LINE__, inN, outN ); 285 return outVector; 286 } 287 287 288 if ( outVector->type.type != PS_TYPE_U32 ) { 288 psError( __func__, " : Line %d - Output vector is not of type U32: out=%d\n",289 __LINE__, outVector->type.type );290 return outVector;291 }292 289 psError( __func__, " : Line %d - Output vector is not of type U32: out=%d\n", 290 __LINE__, outVector->type.type ); 291 return outVector; 292 } 293 293 294 tmpVector = psVectorAlloc( inN, inType ); 294 295 tmpVector->n = inN; 295 296 tmpVector = psVectorSort( tmpVector, inVector ); 296 297 297 298 // Sort output vector 298 299 switch ( inType ) { 299 case PS_TYPE_U8:300 SORT_INDICES( U8 );301 break;302 case PS_TYPE_U16:303 SORT_INDICES( U16 );304 break;305 case PS_TYPE_U32:306 SORT_INDICES( U32 );307 break;308 case PS_TYPE_U64:309 SORT_INDICES( U64 );310 break;311 case PS_TYPE_S8:312 SORT_INDICES( S8 );313 break;314 case PS_TYPE_S16:315 SORT_INDICES( S16 );316 break;317 case PS_TYPE_S32:318 SORT_INDICES( S32 );319 break;320 case PS_TYPE_S64:321 SORT_INDICES( S64 );322 break;323 case PS_TYPE_F32:324 SORT_INDICES( F32 );325 break;326 case PS_TYPE_F64:327 SORT_INDICES( F64 );328 break;329 default:330 psError( __func__, " : Line %d - Invalid psType\n", __LINE__ );331 }332 300 case PS_TYPE_U8: 301 SORT_INDICES( U8 ); 302 break; 303 case PS_TYPE_U16: 304 SORT_INDICES( U16 ); 305 break; 306 case PS_TYPE_U32: 307 SORT_INDICES( U32 ); 308 break; 309 case PS_TYPE_U64: 310 SORT_INDICES( U64 ); 311 break; 312 case PS_TYPE_S8: 313 SORT_INDICES( S8 ); 314 break; 315 case PS_TYPE_S16: 316 SORT_INDICES( S16 ); 317 break; 318 case PS_TYPE_S32: 319 SORT_INDICES( S32 ); 320 break; 321 case PS_TYPE_S64: 322 SORT_INDICES( S64 ); 323 break; 324 case PS_TYPE_F32: 325 SORT_INDICES( F32 ); 326 break; 327 case PS_TYPE_F64: 328 SORT_INDICES( F64 ); 329 break; 330 default: 331 psError( __func__, " : Line %d - Invalid psType\n", __LINE__ ); 332 } 333 333 334 // Free temp memory 334 335 psFree( tmpVector ); 335 336 336 337 return outVector; 337 338 } … … 340 341 { 341 342 if ( psVec == NULL ) { 342 return ;343 }344 343 return ; 344 } 345 345 346 psFree( psVec->data.V ); 346 347 } -
trunk/psLib/src/collections/psVector.h
r1233 r1385 11 11 * @author Ross Harman, MHPCC 12 12 * 13 * @version $Revision: 1.1 3$ $Name: not supported by cvs2svn $14 * @date $Date: 2004-0 7-15 23:52:33$13 * @version $Revision: 1.14 $ $Name: not supported by cvs2svn $ 14 * @date $Date: 2004-08-04 23:37:39 $ 15 15 * 16 16 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/dataManip/psFFT.c
r1366 r1385 5 5 * @author Robert DeSonia, MHPCC 6 6 * 7 * @version $Revision: 1.1 5$ $Name: not supported by cvs2svn $8 * @date $Date: 2004-08-0 2 19:43:59 $7 * @version $Revision: 1.16 $ $Name: not supported by cvs2svn $ 8 * @date $Date: 2004-08-04 23:37:39 $ 9 9 * 10 10 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 33 33 psElemType type; 34 34 fftwf_plan plan; 35 35 36 36 /* got good image data? */ 37 37 if ( in == NULL ) { 38 psFree( out );39 return NULL;40 }41 42 type = in->type.type; 43 38 psFree( out ); 39 return NULL; 40 } 41 42 type = in->type.type; 43 44 44 if ( ( type != PS_TYPE_F32 ) && ( type != PS_TYPE_C32 ) ) { 45 psError( __func__, "Input image must be a 32-bit float or complex image (type=%d)",46 type );47 psFree( out );48 return NULL;49 }50 45 psError( __func__, "Input image must be a 32-bit float or complex image (type=%d)", 46 type ); 47 psFree( out ); 48 return NULL; 49 } 50 51 51 if ( type != PS_TYPE_C32 && direction == PS_FFT_REVERSE ) { 52 psError( __func__, "Input image must be complex image for reverse FFT (type=%d).",53 type );54 psFree( out );55 return NULL;56 57 }58 52 psError( __func__, "Input image must be complex image for reverse FFT (type=%d).", 53 type ); 54 psFree( out ); 55 return NULL; 56 57 } 58 59 59 if ( type != PS_TYPE_F32 && direction == PS_FFT_FORWARD ) { 60 psError( __func__, "Input image must be real image for forward FFT (type=%d).",61 type );62 psFree( out );63 return NULL;64 }65 60 psError( __func__, "Input image must be real image for forward FFT (type=%d).", 61 type ); 62 psFree( out ); 63 return NULL; 64 } 65 66 66 /* make sure the system-level wisdom information is imported. */ 67 67 if ( ! p_fftwWisdomImported ) { 68 fftwf_import_system_wisdom();69 p_fftwWisdomImported = true;70 }71 68 fftwf_import_system_wisdom(); 69 p_fftwWisdomImported = true; 70 } 71 72 72 numRows = in->numRows; 73 73 numCols = in->numCols; 74 74 75 75 out = psImageCopy( out, in, PS_TYPE_C32 ); 76 76 77 77 plan = fftwf_plan_dft_2d( numCols, numRows, 78 78 ( fftwf_complex* ) out->data.C32[ 0 ], … … 80 80 direction, 81 81 P_FFTW_PLAN_RIGOR ); 82 82 83 83 /* check if a plan exists now*/ 84 84 if ( plan == NULL ) { 85 psError( __func__, "Failed to create FFTW plan." );86 psFree( out );87 return NULL;88 }89 85 psError( __func__, "Failed to create FFTW plan." ); 86 psFree( out ); 87 return NULL; 88 } 89 90 90 /* finally, call FFTW with the plan made above */ 91 91 fftwf_execute( plan ); 92 92 93 93 fftwf_destroy_plan( plan ); 94 95 return out; 96 94 95 return out; 96 97 97 } 98 98 … … 103 103 unsigned int numCols; 104 104 unsigned int numRows; 105 106 107 if ( in == NULL ) { 108 psFree( out );109 return NULL;110 }111 105 106 107 if ( in == NULL ) { 108 psFree( out ); 109 return NULL; 110 } 111 112 112 type = in->type.type; 113 113 numCols = in->numCols; 114 114 numRows = in->numRows; 115 115 116 116 /* if not a complex number, this is logically just a copy */ 117 117 if ( ! PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 118 // Warn user, as this is probably not expected119 psLogMsg( __func__, PS_LOG_WARN, "Real portion of a non-Complex type called called for. "120 "Just an image copy was performed." );121 return psImageCopy( out, in, type );122 }123 118 // Warn user, as this is probably not expected 119 psLogMsg( __func__, PS_LOG_WARN, "Real portion of a non-Complex type called called for. " 120 "Just an image copy was performed." ); 121 return psImageCopy( out, in, type ); 122 } 123 124 124 if ( type == PS_TYPE_C32 ) { 125 psF32 * outRow; 126 psC32* inRow; 127 128 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F32 ); 129 for ( unsigned int row = 0;row < numRows;row++ ) { 130 outRow = out->data.F32[ row ]; 131 inRow = in->data.C32[ row ]; 132 133 for ( unsigned int col = 0;col < numCols;col++ ) { 134 outRow[ col ] = crealf( inRow[ col ] ); 135 } 136 } 137 } else if ( type == PS_TYPE_C64 ) { 125 psF32 * outRow; 126 psC32* inRow; 127 128 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F32 ); 129 for ( unsigned int row = 0;row < numRows;row++ ) { 130 outRow = out->data.F32[ row ]; 131 inRow = in->data.C32[ row ]; 132 133 for ( unsigned int col = 0;col < numCols;col++ ) { 134 outRow[ col ] = crealf( inRow[ col ] ); 135 } 136 } 137 } else 138 if ( type == PS_TYPE_C64 ) { 138 139 psF64 * outRow; 139 140 psC64* inRow; 140 141 141 142 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F64 ); 142 143 for ( unsigned int row = 0;row < numRows;row++ ) { 143 outRow = out->data.F64[ row ]; 144 inRow = in->data.C64[ row ]; 145 146 for ( unsigned int col = 0;col < numCols;col++ ) { 147 outRow[ col ] = creal( inRow[ col ] ); 148 } 144 outRow = out->data.F64[ row ]; 145 inRow = in->data.C64[ row ]; 146 147 for ( unsigned int col = 0;col < numCols;col++ ) { 148 outRow[ col ] = creal( inRow[ col ] ); 149 149 } 150 } 150 151 } else { 151 152 psError( __func__, "Can not extract real component from given image type (%d).", … … 154 155 return NULL; 155 156 } 156 157 157 158 return out; 158 159 } … … 163 164 unsigned int numCols; 164 165 unsigned int numRows; 165 166 167 if ( in == NULL ) { 168 psFree( out );169 return NULL;170 }171 166 167 168 if ( in == NULL ) { 169 psFree( out ); 170 return NULL; 171 } 172 172 173 type = in->type.type; 173 174 numCols = in->numCols; 174 175 numRows = in->numRows; 175 176 176 177 /* if not a complex number, this is logically just zeroed image of same size */ 177 178 if ( ! PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 178 // Warn user, as this is probably not expected179 psLogMsg( __func__, PS_LOG_WARN, "Imaginary portion of a non-Complex type called for. "180 "A zero image was returned." );181 out = psImageRecycle( out, numCols, numRows, type );182 memset( out->data.V[ 0 ], 0, PSELEMTYPE_SIZEOF( type ) * numCols * numRows );183 return out;184 }185 179 // Warn user, as this is probably not expected 180 psLogMsg( __func__, PS_LOG_WARN, "Imaginary portion of a non-Complex type called for. " 181 "A zero image was returned." ); 182 out = psImageRecycle( out, numCols, numRows, type ); 183 memset( out->data.V[ 0 ], 0, PSELEMTYPE_SIZEOF( type ) * numCols * numRows ); 184 return out; 185 } 186 186 187 if ( type == PS_TYPE_C32 ) { 187 psF32 * outRow; 188 psC32* inRow; 189 190 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F32 ); 191 for ( unsigned int row = 0;row < numRows;row++ ) { 192 outRow = out->data.F32[ row ]; 193 inRow = in->data.C32[ row ]; 194 195 for ( unsigned int col = 0;col < numCols;col++ ) { 196 outRow[ col ] = cimagf( inRow[ col ] ); 197 } 198 } 199 } else if ( type == PS_TYPE_C64 ) { 188 psF32 * outRow; 189 psC32* inRow; 190 191 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F32 ); 192 for ( unsigned int row = 0;row < numRows;row++ ) { 193 outRow = out->data.F32[ row ]; 194 inRow = in->data.C32[ row ]; 195 196 for ( unsigned int col = 0;col < numCols;col++ ) { 197 outRow[ col ] = cimagf( inRow[ col ] ); 198 } 199 } 200 } else 201 if ( type == PS_TYPE_C64 ) { 200 202 psF64 * outRow; 201 203 psC64* inRow; 202 204 203 205 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F64 ); 204 206 for ( unsigned int row = 0;row < numRows;row++ ) { 205 outRow = out->data.F64[ row ]; 206 inRow = in->data.C64[ row ]; 207 208 for ( unsigned int col = 0;col < numCols;col++ ) { 209 outRow[ col ] = cimag( inRow[ col ] ); 210 } 207 outRow = out->data.F64[ row ]; 208 inRow = in->data.C64[ row ]; 209 210 for ( unsigned int col = 0;col < numCols;col++ ) { 211 outRow[ col ] = cimag( inRow[ col ] ); 211 212 } 213 } 212 214 } else { 213 215 psError( __func__, "Can not extract imaginary component from given image type (%d).", … … 216 218 return NULL; 217 219 } 218 220 219 221 return out; 220 222 } … … 225 227 unsigned int numCols; 226 228 unsigned int numRows; 227 228 229 230 229 231 if ( real == NULL || imag == NULL ) { 230 psFree( out );231 return NULL;232 }233 232 psFree( out ); 233 return NULL; 234 } 235 234 236 type = real->type.type; 235 237 numCols = real->numCols; 236 238 numRows = real->numRows; 237 239 238 240 if ( imag->type.type != type ) { 239 psError( __func__, "The inputs to psImageComplex must be the same type." );240 psFree( out );241 return NULL;242 }243 241 psError( __func__, "The inputs to psImageComplex must be the same type." ); 242 psFree( out ); 243 return NULL; 244 } 245 244 246 if ( imag->numCols != numCols || 245 247 imag->numRows != numRows ) { 246 psError( __func__, "The inputs to psImageComplex must be the same dimensions." );247 psFree( out );248 return NULL;249 }250 248 psError( __func__, "The inputs to psImageComplex must be the same dimensions." ); 249 psFree( out ); 250 return NULL; 251 } 252 251 253 if ( PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 252 psError( __func__, "The inputs to psImageComplex can not be complex." );253 psFree( out );254 return NULL;255 }256 254 psError( __func__, "The inputs to psImageComplex can not be complex." ); 255 psFree( out ); 256 return NULL; 257 } 258 257 259 if ( type != PS_TYPE_F32 && type != PS_TYPE_F64 ) { 258 psError( __func__, "The input type to psImageComplex must be a floating point." );259 psFree( out );260 return NULL;261 }262 260 psError( __func__, "The input type to psImageComplex must be a floating point." ); 261 psFree( out ); 262 return NULL; 263 } 264 263 265 if ( type == PS_TYPE_F32 ) { 264 psC32 * outRow; 265 psF32* realRow; 266 psF32* imagRow; 267 268 out = psImageRecycle( out, numCols, numRows, PS_TYPE_C32 ); 269 270 for ( unsigned int row = 0;row < numRows;row++ ) { 271 outRow = out->data.C32[ row ]; 272 realRow = real->data.F32[ row ]; 273 imagRow = imag->data.F32[ row ]; 274 275 for ( unsigned int col = 0;col < numCols;col++ ) { 276 outRow[ col ] = realRow[ col ] + I * imagRow[ col ]; 277 } 278 } 279 } else if ( type == PS_TYPE_F64 ) { 266 psC32 * outRow; 267 psF32* realRow; 268 psF32* imagRow; 269 270 out = psImageRecycle( out, numCols, numRows, PS_TYPE_C32 ); 271 272 for ( unsigned int row = 0;row < numRows;row++ ) { 273 outRow = out->data.C32[ row ]; 274 realRow = real->data.F32[ row ]; 275 imagRow = imag->data.F32[ row ]; 276 277 for ( unsigned int col = 0;col < numCols;col++ ) { 278 outRow[ col ] = realRow[ col ] + I * imagRow[ col ]; 279 } 280 } 281 } else 282 if ( type == PS_TYPE_F64 ) { 280 283 psC64 * outRow; 281 284 psF64* realRow; 282 285 psF64* imagRow; 283 286 284 287 out = psImageRecycle( out, numCols, numRows, PS_TYPE_C64 ); 285 288 for ( unsigned int row = 0;row < numRows;row++ ) { 286 outRow = out->data.C64[ row ]; 287 realRow = real->data.F64[ row ]; 288 imagRow = imag->data.F64[ row ]; 289 290 for ( unsigned int col = 0;col < numCols;col++ ) { 291 outRow[ col ] = realRow[ col ] + I * imagRow[ col ]; 292 } 289 outRow = out->data.C64[ row ]; 290 realRow = real->data.F64[ row ]; 291 imagRow = imag->data.F64[ row ]; 292 293 for ( unsigned int col = 0;col < numCols;col++ ) { 294 outRow[ col ] = realRow[ col ] + I * imagRow[ col ]; 293 295 } 296 } 294 297 } else { 295 298 psError( __func__, "Can not merge real and imaginary portions for given image type (%d).", … … 298 301 return NULL; 299 302 } 300 303 301 304 return out; 302 305 } … … 307 310 unsigned int numCols; 308 311 unsigned int numRows; 309 310 311 if ( in == NULL ) { 312 psFree( out );313 return NULL;314 }315 312 313 314 if ( in == NULL ) { 315 psFree( out ); 316 return NULL; 317 } 318 316 319 type = in->type.type; 317 320 numCols = in->numCols; 318 321 numRows = in->numRows; 319 322 320 323 /* if not a complex number, this is logically just a image copy */ 321 324 if ( ! PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 322 // Warn user, as this is probably not expected323 psLogMsg( __func__, PS_LOG_WARN, "Complex Conjugate of a non-Complex type called for. "324 "Image copy was performed instead." );325 return psImageCopy( out, in, type );326 }327 325 // Warn user, as this is probably not expected 326 psLogMsg( __func__, PS_LOG_WARN, "Complex Conjugate of a non-Complex type called for. " 327 "Image copy was performed instead." ); 328 return psImageCopy( out, in, type ); 329 } 330 328 331 if ( type == PS_TYPE_C32 ) { 329 psC32 * outRow; 330 psC32* inRow; 331 332 out = psImageRecycle( out, numCols, numRows, PS_TYPE_C32 ); 333 for ( unsigned int row = 0;row < numRows;row++ ) { 334 outRow = out->data.C32[ row ]; 335 inRow = in->data.C32[ row ]; 336 337 for ( unsigned int col = 0;col < numCols;col++ ) { 338 outRow[ col ] = crealf( inRow[ col ] ) - I * cimagf( inRow[ col ] ); 339 } 340 } 341 } else if ( type == PS_TYPE_C64 ) { 332 psC32 * outRow; 333 psC32* inRow; 334 335 out = psImageRecycle( out, numCols, numRows, PS_TYPE_C32 ); 336 for ( unsigned int row = 0;row < numRows;row++ ) { 337 outRow = out->data.C32[ row ]; 338 inRow = in->data.C32[ row ]; 339 340 for ( unsigned int col = 0;col < numCols;col++ ) { 341 outRow[ col ] = crealf( inRow[ col ] ) - I * cimagf( inRow[ col ] ); 342 } 343 } 344 } else 345 if ( type == PS_TYPE_C64 ) { 342 346 psC64 * outRow; 343 347 psC64* inRow; 344 348 345 349 out = psImageRecycle( out, numCols, numRows, PS_TYPE_C64 ); 346 350 for ( unsigned int row = 0;row < numRows;row++ ) { 347 outRow = out->data.C64[ row ]; 348 inRow = in->data.C64[ row ]; 349 350 for ( unsigned int col = 0;col < numCols;col++ ) { 351 outRow[ col ] = creal( inRow[ col ] ) - I * cimag( inRow[ col ] ); 352 } 351 outRow = out->data.C64[ row ]; 352 inRow = in->data.C64[ row ]; 353 354 for ( unsigned int col = 0;col < numCols;col++ ) { 355 outRow[ col ] = creal( inRow[ col ] ) - I * cimag( inRow[ col ] ); 353 356 } 357 } 354 358 } else { 355 359 psError( __func__, "Can not compute complex conjugate for given image type (%d).", … … 358 362 return NULL; 359 363 } 360 364 361 365 return out; 362 366 } … … 368 372 unsigned int numRows; 369 373 int numElementsSquared; 370 371 if ( in == NULL ) { 372 psFree( out );373 return NULL;374 }375 374 375 if ( in == NULL ) { 376 psFree( out ); 377 return NULL; 378 } 379 376 380 type = in->type.type; 377 381 numCols = in->numCols; 378 382 numRows = in->numRows; 379 383 numElementsSquared = numCols * numCols * numRows * numRows; 380 384 381 385 /* if not a complex number, this is not implemented */ 382 386 if ( ! PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 383 psError( __func__, "Power Spectrum for non-complex inputs is not implemented." );384 psFree( out );385 return NULL;386 }387 387 psError( __func__, "Power Spectrum for non-complex inputs is not implemented." ); 388 psFree( out ); 389 return NULL; 390 } 391 388 392 if ( type == PS_TYPE_C32 ) { 389 psF32 * outRow; 390 psC32* inRow; 391 psF32 real; 392 psF32 imag; 393 394 395 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F32 ); 396 for ( unsigned int row = 0;row < numRows;row++ ) { 397 outRow = out->data.F32[ row ]; 398 inRow = in->data.C32[ row ]; 399 400 for ( unsigned int col = 0;col < numCols;col++ ) { 401 real = crealf( inRow[ col ] ); 402 imag = cimagf( inRow[ col ] ); 403 outRow[ col ] = ( real * real + imag * imag ) / numElementsSquared; 404 } 405 } 406 } else if ( type == PS_TYPE_C64 ) { 393 psF32 * outRow; 394 psC32* inRow; 395 psF32 real; 396 psF32 imag; 397 398 399 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F32 ); 400 for ( unsigned int row = 0;row < numRows;row++ ) { 401 outRow = out->data.F32[ row ]; 402 inRow = in->data.C32[ row ]; 403 404 for ( unsigned int col = 0;col < numCols;col++ ) { 405 real = crealf( inRow[ col ] ); 406 imag = cimagf( inRow[ col ] ); 407 outRow[ col ] = ( real * real + imag * imag ) / numElementsSquared; 408 } 409 } 410 } else 411 if ( type == PS_TYPE_C64 ) { 407 412 psF64 * outRow; 408 413 psC64* inRow; 409 414 psF64 real; 410 415 psF64 imag; 411 412 416 417 413 418 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F64 ); 414 419 for ( unsigned int row = 0;row < numRows;row++ ) { 415 outRow = out->data.F64[ row ]; 416 inRow = in->data.C64[ row ]; 417 418 for ( unsigned int col = 0;col < numCols;col++ ) { 419 real = crealf( inRow[ col ] ); 420 imag = cimagf( inRow[ col ] ); 421 outRow[ col ] = real * real + imag * imag / numElementsSquared; 422 } 420 outRow = out->data.F64[ row ]; 421 inRow = in->data.C64[ row ]; 422 423 for ( unsigned int col = 0;col < numCols;col++ ) { 424 real = crealf( inRow[ col ] ); 425 imag = cimagf( inRow[ col ] ); 426 outRow[ col ] = real * real + imag * imag / numElementsSquared; 423 427 } 428 } 424 429 } else { 425 430 psError( __func__, "Can not power spectrum for given image type (%d).", … … 428 433 return NULL; 429 434 } 430 431 return out; 432 435 436 return out; 437 433 438 } 434 439 … … 440 445 psElemType type; 441 446 fftwf_plan plan; 442 447 443 448 /* got good image data? */ 444 449 if ( in == NULL ) { 445 psFree( out );446 return NULL;447 }448 449 type = in->type.type; 450 450 psFree( out ); 451 return NULL; 452 } 453 454 type = in->type.type; 455 451 456 if ( ( type != PS_TYPE_F32 ) && ( type != PS_TYPE_C32 ) ) { 452 psError( __func__, "Input image must be a 32-bit float or complex image (type=%d)",453 type );454 psFree( out );455 return NULL;456 }457 457 psError( __func__, "Input image must be a 32-bit float or complex image (type=%d)", 458 type ); 459 psFree( out ); 460 return NULL; 461 } 462 458 463 if ( ( type != PS_TYPE_C32 ) && ( direction == PS_FFT_REVERSE ) ) { 459 psError( __func__, "Input image must be complex image for reverse FFT (type=%d).",460 type );461 psFree( out );462 return NULL;463 464 }465 464 psError( __func__, "Input image must be complex image for reverse FFT (type=%d).", 465 type ); 466 psFree( out ); 467 return NULL; 468 469 } 470 466 471 if ( ( type != PS_TYPE_F32 ) && ( direction == PS_FFT_FORWARD ) ) { 467 psError( __func__, "Input image must be real image for forward FFT (type=%d).",468 type );469 psFree( out );470 return NULL;471 }472 472 psError( __func__, "Input image must be real image for forward FFT (type=%d).", 473 type ); 474 psFree( out ); 475 return NULL; 476 } 477 473 478 /* make sure the system-level wisdom information is imported. */ 474 479 if ( ! p_fftwWisdomImported ) { 475 fftwf_import_system_wisdom();476 p_fftwWisdomImported = true;477 }478 480 fftwf_import_system_wisdom(); 481 p_fftwWisdomImported = true; 482 } 483 479 484 numElements = in->n; 480 485 481 486 out = psVectorRecycle( out, PS_TYPE_C32, numElements ); 482 487 out->n = numElements; 483 488 484 489 if ( type == PS_TYPE_F32 ) { 485 // need to convert to complex486 psC32 * outVec = out->data.C32;487 psF32* inVec = in->data.F32;488 for ( unsigned int i = 0;i < numElements;i++ ) {489 outVec[ i ] = inVec[ i ];490 }491 } else {492 psC32* outVec = out->data.C32;493 psC32* inVec = in->data.C32;494 for ( unsigned int i = 0;i < numElements;i++ ) {495 outVec[ i ] = inVec[ i ];496 }497 }498 490 // need to convert to complex 491 psC32 * outVec = out->data.C32; 492 psF32* inVec = in->data.F32; 493 for ( unsigned int i = 0;i < numElements;i++ ) { 494 outVec[ i ] = inVec[ i ]; 495 } 496 } else { 497 psC32* outVec = out->data.C32; 498 psC32* inVec = in->data.C32; 499 for ( unsigned int i = 0;i < numElements;i++ ) { 500 outVec[ i ] = inVec[ i ]; 501 } 502 } 503 499 504 plan = fftwf_plan_dft_1d( numElements, 500 505 ( fftwf_complex* ) out->data.C32, … … 502 507 direction, 503 508 P_FFTW_PLAN_RIGOR ); 504 509 505 510 /* check if a plan exists now*/ 506 511 if ( plan == NULL ) { 507 psError( __func__, "Failed to create FFTW plan." );508 psFree( out );509 return NULL;510 }511 512 psError( __func__, "Failed to create FFTW plan." ); 513 psFree( out ); 514 return NULL; 515 } 516 512 517 /* finally, call FFTW with the plan made above */ 513 518 fftwf_execute( plan ); 514 519 515 520 fftwf_destroy_plan( plan ); 516 521 517 522 return out; 518 523 } … … 523 528 psElemType type; 524 529 unsigned int numElements; 525 526 if ( in == NULL ) { 527 psFree( out );528 return NULL;529 }530 530 531 if ( in == NULL ) { 532 psFree( out ); 533 return NULL; 534 } 535 531 536 type = in->type.type; 532 537 numElements = in->n; 533 538 534 539 /* if not a complex number, this is logically just a copy */ 535 540 if ( ! PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 536 // Warn user, as this is probably not expected537 psLogMsg( __func__, PS_LOG_WARN, "Real portion of a non-Complex type called called for. "538 "Just a vector copy was performed." );539 out = psVectorRecycle( out, type, numElements );540 out->n = numElements;541 memcpy( out->data.V, in->data.V, numElements * PSELEMTYPE_SIZEOF( type ) );542 return out;543 }544 541 // Warn user, as this is probably not expected 542 psLogMsg( __func__, PS_LOG_WARN, "Real portion of a non-Complex type called called for. " 543 "Just a vector copy was performed." ); 544 out = psVectorRecycle( out, type, numElements ); 545 out->n = numElements; 546 memcpy( out->data.V, in->data.V, numElements * PSELEMTYPE_SIZEOF( type ) ); 547 return out; 548 } 549 545 550 if ( type == PS_TYPE_C32 ) { 546 psF32 * outVec;547 psC32* inVec = in->data.C32;548 549 out = psVectorRecycle( out, PS_TYPE_F32, numElements );550 out->n = numElements;551 outVec = out->data.F32;552 553 for ( unsigned int i = 0;i < numElements;i++ ) {554 outVec[ i ] = crealf( inVec[ i ] );555 }556 } else {557 psError( __func__, "Can not extract real component from given vector type (%d).",558 type );559 psFree( out );560 return NULL;561 }562 551 psF32 * outVec; 552 psC32* inVec = in->data.C32; 553 554 out = psVectorRecycle( out, PS_TYPE_F32, numElements ); 555 out->n = numElements; 556 outVec = out->data.F32; 557 558 for ( unsigned int i = 0;i < numElements;i++ ) { 559 outVec[ i ] = crealf( inVec[ i ] ); 560 } 561 } else { 562 psError( __func__, "Can not extract real component from given vector type (%d).", 563 type ); 564 psFree( out ); 565 return NULL; 566 } 567 563 568 return out; 564 569 } … … 568 573 psElemType type; 569 574 unsigned int numElements; 570 571 572 if ( in == NULL ) { 573 psFree( out );574 return NULL;575 }576 575 576 577 if ( in == NULL ) { 578 psFree( out ); 579 return NULL; 580 } 581 577 582 type = in->type.type; 578 583 numElements = in->n; 579 584 580 585 /* if not a complex number, this is logically just zeroed image of same size */ 581 586 if ( ! PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 582 // Warn user, as this is probably not expected583 psLogMsg( __func__, PS_LOG_WARN, "Imaginary portion of a non-Complex type called for. "584 "A zeroed vector was returned." );585 out = psVectorRecycle( out, type, numElements );586 out->n = numElements;587 memset( out->data.V, 0, PSELEMTYPE_SIZEOF( type ) * numElements );588 return out;589 }590 587 // Warn user, as this is probably not expected 588 psLogMsg( __func__, PS_LOG_WARN, "Imaginary portion of a non-Complex type called for. " 589 "A zeroed vector was returned." ); 590 out = psVectorRecycle( out, type, numElements ); 591 out->n = numElements; 592 memset( out->data.V, 0, PSELEMTYPE_SIZEOF( type ) * numElements ); 593 return out; 594 } 595 591 596 if ( type == PS_TYPE_C32 ) { 592 psF32 * outVec;593 psC32* inVec = in->data.C32;594 595 out = psVectorRecycle( out, PS_TYPE_F32, numElements );596 out->n = numElements;597 outVec = out->data.F32;598 599 for ( unsigned int i = 0;i < numElements;i++ ) {600 outVec[ i ] = cimagf( inVec[ i ] );601 }602 } else {603 psError( __func__, "Can not extract imaginary component from given vector type (%d).",604 type );605 psFree( out );606 return NULL;607 }608 597 psF32 * outVec; 598 psC32* inVec = in->data.C32; 599 600 out = psVectorRecycle( out, PS_TYPE_F32, numElements ); 601 out->n = numElements; 602 outVec = out->data.F32; 603 604 for ( unsigned int i = 0;i < numElements;i++ ) { 605 outVec[ i ] = cimagf( inVec[ i ] ); 606 } 607 } else { 608 psError( __func__, "Can not extract imaginary component from given vector type (%d).", 609 type ); 610 psFree( out ); 611 return NULL; 612 } 613 609 614 return out; 610 615 } … … 614 619 psElemType type; 615 620 unsigned int numElements; 616 617 621 622 618 623 if ( real == NULL || imag == NULL ) { 619 psFree( out );620 return NULL;621 }622 624 psFree( out ); 625 return NULL; 626 } 627 623 628 type = real->type.type; 624 629 if ( real->n < imag->n ) { 625 numElements = real->n;626 } else {627 numElements = imag->n;628 }629 630 numElements = real->n; 631 } else { 632 numElements = imag->n; 633 } 634 630 635 if ( imag->type.type != type ) { 631 psError( __func__, "The inputs to psVectorComplex must be the same type." );632 psFree( out );633 return NULL;634 }635 636 psError( __func__, "The inputs to psVectorComplex must be the same type." ); 637 psFree( out ); 638 return NULL; 639 } 640 636 641 if ( PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 637 psError( __func__, "The inputs to psVectorComplex can not be complex." );638 psFree( out );639 return NULL;640 }641 642 psError( __func__, "The inputs to psVectorComplex can not be complex." ); 643 psFree( out ); 644 return NULL; 645 } 646 642 647 if ( type == PS_TYPE_F32 ) { 643 psC32 * outVec;644 psF32* realVec = real->data.F32;645 psF32* imagVec = imag->data.F32;646 647 out = psVectorRecycle( out, PS_TYPE_C32, numElements );648 out->n = numElements;649 outVec = out->data.C32;650 651 for ( unsigned int i = 0;i < numElements;i++ ) {652 outVec[ i ] = realVec[ i ] + I * imagVec[ i ];653 }654 } else {655 psError( __func__, "Can not merge real and imaginary portions for given vector type (%d).",656 type );657 psFree( out );658 return NULL;659 }660 648 psC32 * outVec; 649 psF32* realVec = real->data.F32; 650 psF32* imagVec = imag->data.F32; 651 652 out = psVectorRecycle( out, PS_TYPE_C32, numElements ); 653 out->n = numElements; 654 outVec = out->data.C32; 655 656 for ( unsigned int i = 0;i < numElements;i++ ) { 657 outVec[ i ] = realVec[ i ] + I * imagVec[ i ]; 658 } 659 } else { 660 psError( __func__, "Can not merge real and imaginary portions for given vector type (%d).", 661 type ); 662 psFree( out ); 663 return NULL; 664 } 665 661 666 return out; 662 667 } … … 666 671 psElemType type; 667 672 unsigned int numElements; 668 669 670 if ( in == NULL ) { 671 psFree( out );672 return NULL;673 }674 673 674 675 if ( in == NULL ) { 676 psFree( out ); 677 return NULL; 678 } 679 675 680 type = in->type.type; 676 681 numElements = in->n; 677 682 678 683 /* if not a complex number, this is logically just a image copy */ 679 684 if ( ! PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 680 // Warn user, as this is probably not expected681 psLogMsg( __func__, PS_LOG_WARN, "Complex Conjugate of a non-Complex type called for. "682 "Vector copy was performed instead." );683 684 out = psVectorRecycle( out, type, numElements );685 out->n = numElements;686 memcpy( out->data.V, in->data.V, PSELEMTYPE_SIZEOF( type ) * numElements );687 return out;688 }689 685 // Warn user, as this is probably not expected 686 psLogMsg( __func__, PS_LOG_WARN, "Complex Conjugate of a non-Complex type called for. " 687 "Vector copy was performed instead." ); 688 689 out = psVectorRecycle( out, type, numElements ); 690 out->n = numElements; 691 memcpy( out->data.V, in->data.V, PSELEMTYPE_SIZEOF( type ) * numElements ); 692 return out; 693 } 694 690 695 if ( type == PS_TYPE_C32 ) { 691 psC32 * outVec;692 psC32* inVec = in->data.C32;693 694 out = psVectorRecycle( out, PS_TYPE_C32, numElements );695 out->n = numElements;696 outVec = out->data.C32;697 698 for ( unsigned int i = 0;i < numElements;i++ ) {699 outVec[ i ] = crealf( inVec[ i ] ) - I * cimagf( inVec[ i ] );700 }701 } else {702 psError( __func__, "Can not compute complex conjugate for given vector type (%d).",703 type );704 psFree( out );705 return NULL;706 }707 696 psC32 * outVec; 697 psC32* inVec = in->data.C32; 698 699 out = psVectorRecycle( out, PS_TYPE_C32, numElements ); 700 out->n = numElements; 701 outVec = out->data.C32; 702 703 for ( unsigned int i = 0;i < numElements;i++ ) { 704 outVec[ i ] = crealf( inVec[ i ] ) - I * cimagf( inVec[ i ] ); 705 } 706 } else { 707 psError( __func__, "Can not compute complex conjugate for given vector type (%d).", 708 type ); 709 psFree( out ); 710 return NULL; 711 } 712 708 713 return out; 709 714 } … … 716 721 unsigned int inHalfNumElements; 717 722 unsigned int inNumElementsSquared; 718 719 if ( in == NULL ) { 720 psFree( out );721 return NULL;722 }723 723 724 if ( in == NULL ) { 725 psFree( out ); 726 return NULL; 727 } 728 724 729 type = in->type.type; 725 730 inNumElements = in->n; … … 727 732 inHalfNumElements = inNumElements / 2; 728 733 outNumElements = inHalfNumElements + 1; 729 734 730 735 /* if not a complex number, this is not implemented */ 731 736 if ( ! PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 732 psError( __func__, "Power Spectrum for non-complex inputs is not implemented." );733 psFree( out );734 return NULL;735 }736 737 psError( __func__, "Power Spectrum for non-complex inputs is not implemented." ); 738 psFree( out ); 739 return NULL; 740 } 741 737 742 if ( type == PS_TYPE_C32 ) { 738 psF32 * outVec;739 psC32* inVec = in->data.C32;740 psF32 inAbs1;741 psF32 inAbs2;742 743 out = psVectorRecycle( out, PS_TYPE_F32, outNumElements );744 out->n = outNumElements;745 outVec = out->data.F32;746 747 // from ADD: P_0 = |C_0|^2/N^2748 inAbs1 = cabsf( inVec[ 0 ] );749 outVec[ 0 ] = inAbs1 * inAbs1 / inNumElementsSquared;750 751 // from ADD: P_j = (|C_j|^2+|C_N-j|^2)/N^2, where j = 1,2,...,(N/2-1)752 for ( unsigned int i = 1;i < inHalfNumElements;i++ ) {753 inAbs1 = cabsf( inVec[ i ] );754 inAbs2 = cabsf( inVec[ inNumElements - i ] );755 outVec[ i ] = ( inAbs1 * inAbs1 + inAbs2 * inAbs2 ) / inNumElementsSquared;756 }757 758 // from ADD: P_N/2 = |C_N/2|^2/N^2759 inAbs1 = cabsf( inVec[ inHalfNumElements ] );760 outVec[ inHalfNumElements ] = inAbs1 * inAbs1 / inNumElementsSquared;761 } else {762 psError( __func__, "Can not power spectrum for given vector type (%d).",763 type );764 psFree( out );765 return NULL;766 }767 768 return out; 769 770 } 743 psF32 * outVec; 744 psC32* inVec = in->data.C32; 745 psF32 inAbs1; 746 psF32 inAbs2; 747 748 out = psVectorRecycle( out, PS_TYPE_F32, outNumElements ); 749 out->n = outNumElements; 750 outVec = out->data.F32; 751 752 // from ADD: P_0 = |C_0|^2/N^2 753 inAbs1 = cabsf( inVec[ 0 ] ); 754 outVec[ 0 ] = inAbs1 * inAbs1 / inNumElementsSquared; 755 756 // from ADD: P_j = (|C_j|^2+|C_N-j|^2)/N^2, where j = 1,2,...,(N/2-1) 757 for ( unsigned int i = 1;i < inHalfNumElements;i++ ) { 758 inAbs1 = cabsf( inVec[ i ] ); 759 inAbs2 = cabsf( inVec[ inNumElements - i ] ); 760 outVec[ i ] = ( inAbs1 * inAbs1 + inAbs2 * inAbs2 ) / inNumElementsSquared; 761 } 762 763 // from ADD: P_N/2 = |C_N/2|^2/N^2 764 inAbs1 = cabsf( inVec[ inHalfNumElements ] ); 765 outVec[ inHalfNumElements ] = inAbs1 * inAbs1 / inNumElementsSquared; 766 } else { 767 psError( __func__, "Can not power spectrum for given vector type (%d).", 768 type ); 769 psFree( out ); 770 return NULL; 771 } 772 773 return out; 774 775 } -
trunk/psLib/src/dataManip/psFFT.h
r974 r1385 7 7 * @author Robert DeSonia, MHPCC 8 8 * 9 * @version $Revision: 1. 6$ $Name: not supported by cvs2svn $10 * @date $Date: 2004-0 6-10 01:58:06$9 * @version $Revision: 1.7 $ $Name: not supported by cvs2svn $ 10 * @date $Date: 2004-08-04 23:37:39 $ 11 11 * 12 12 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/dataManip/psFunctions.c
r1342 r1385 7 7 * polynomials. It also contains a Gaussian functions. 8 8 * 9 * @version $Revision: 1.1 8$ $Name: not supported by cvs2svn $10 * @date $Date: 2004-0 7-29 23:34:24$9 * @version $Revision: 1.19 $ $Name: not supported by cvs2svn $ 10 * @date $Date: 2004-08-04 23:37:39 $ 11 11 * 12 12 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/dataManip/psFunctions.h
r1382 r1385 12 12 * @author George Gusciora, MHPCC 13 13 * 14 * @version $Revision: 1.1 2$ $Name: not supported by cvs2svn $15 * @date $Date: 2004-08-04 2 2:11:09 $14 * @version $Revision: 1.13 $ $Name: not supported by cvs2svn $ 15 * @date $Date: 2004-08-04 23:37:39 $ 16 16 * 17 17 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 39 39 bool normal ///< Indicates whether result should be normalized 40 40 ); 41 42 41 42 43 43 /** Produce a vector of random numbers from a Gaussian distribution with 44 44 the specified mean and sigma */ … … 46 46 float sigma, ///< The sigma of the Gaussian 47 47 int Npts ); ///< The size of the vector 48 49 50 51 52 48 49 50 51 52 53 53 /** One-dimensional polynomial */ 54 54 typedef struct 55 {56 int n; ///< Number of terms57 float *coeff; ///< Coefficients58 float *coeffErr; ///< Error in coefficients59 char *mask; ///< Coefficient mask60 }55 { 56 int n; ///< Number of terms 57 float *coeff; ///< Coefficients 58 float *coeffErr; ///< Error in coefficients 59 char *mask; ///< Coefficient mask 60 } 61 61 psPolynomial1D; 62 62 63 63 /** Two-dimensional polynomial */ 64 64 typedef struct 65 {66 int nX, nY; ///< Number of terms in x and y67 float **coeff; ///< Coefficients68 float **coeffErr; ///< Error in coefficients69 char **mask; ///< Coefficients mask70 }65 { 66 int nX, nY; ///< Number of terms in x and y 67 float **coeff; ///< Coefficients 68 float **coeffErr; ///< Error in coefficients 69 char **mask; ///< Coefficients mask 70 } 71 71 psPolynomial2D; 72 72 73 73 /** Three-dimensional polynomial */ 74 74 typedef struct 75 {76 int nX, nY, nZ; ///< Number of terms in x, y and z77 float ***coeff; ///< Coefficients78 float ***coeffErr; ///< Error in coefficients79 char ***mask; ///< Coefficients mask80 }75 { 76 int nX, nY, nZ; ///< Number of terms in x, y and z 77 float ***coeff; ///< Coefficients 78 float ***coeffErr; ///< Error in coefficients 79 char ***mask; ///< Coefficients mask 80 } 81 81 psPolynomial3D; 82 82 83 83 /** Four-dimensional polynomial */ 84 84 typedef struct 85 {86 int nW, nX, nY, nZ; ///< Number of terms in w, x, y and z87 float ****coeff; ///< Coefficients88 float ****coeffErr; ///< Error in coefficients89 char ****mask; ///< Coefficients mask90 }85 { 86 int nW, nX, nY, nZ; ///< Number of terms in w, x, y and z 87 float ****coeff; ///< Coefficients 88 float ****coeffErr; ///< Error in coefficients 89 char ****mask; ///< Coefficients mask 90 } 91 91 psPolynomial4D; 92 92 … … 106 106 psPolynomial4D *psPolynomial4DAlloc( int nW, int nX, int nY, int nZ ///< Number of terms in w, x, y and z 107 107 ); 108 108 109 109 /** Evaluate 1D polynomial */ 110 110 float … … 112 112 const psPolynomial1D *myPoly ///< Coefficients for the polynomial 113 113 ); 114 114 115 115 /** Evaluate 2D polynomial */ 116 116 float … … 119 119 const psPolynomial2D *myPoly ///< Coefficients for the polynomial 120 120 ); 121 121 122 122 /** Evaluate 3D polynomial */ 123 123 float … … 127 127 const psPolynomial3D *myPoly ///< Coefficients for the polynomial 128 128 ); 129 129 130 130 /** Evaluate 4D polynomial */ 131 131 float … … 136 136 const psPolynomial4D *myPoly ///< Coefficients for the polynomial 137 137 ); 138 138 139 139 /*****************************************************************************/ 140 140 … … 143 143 /** Double-precision one-dimensional polynomial */ 144 144 typedef struct 145 {146 int n; ///< Number of terms147 double *coeff; ///< Coefficients148 double *coeffErr; ///< Error in coefficients149 char *mask; ///< Coefficient mask150 }145 { 146 int n; ///< Number of terms 147 double *coeff; ///< Coefficients 148 double *coeffErr; ///< Error in coefficients 149 char *mask; ///< Coefficient mask 150 } 151 151 psDPolynomial1D; 152 152 153 153 /** Double-precision two-dimensional polynomial */ 154 154 typedef struct 155 {156 int nX, nY; ///< Number of terms in x and y157 double **coeff; ///< Coefficients158 double **coeffErr; ///< Error in coefficients159 char **mask; ///< Coefficients mask160 }155 { 156 int nX, nY; ///< Number of terms in x and y 157 double **coeff; ///< Coefficients 158 double **coeffErr; ///< Error in coefficients 159 char **mask; ///< Coefficients mask 160 } 161 161 psDPolynomial2D; 162 162 163 163 /** Double-precision three-dimensional polynomial */ 164 164 typedef struct 165 {166 int nX, nY, nZ; ///< Number of terms in x, y and z167 double ***coeff; ///< Coefficients168 double ***coeffErr; ///< Error in coefficients169 char ***mask; ///< Coefficient mask170 }165 { 166 int nX, nY, nZ; ///< Number of terms in x, y and z 167 double ***coeff; ///< Coefficients 168 double ***coeffErr; ///< Error in coefficients 169 char ***mask; ///< Coefficient mask 170 } 171 171 psDPolynomial3D; 172 172 173 173 /** Double-precision four-dimensional polynomial */ 174 174 typedef struct 175 {176 int nW, nX, nY, nZ; ///< Number of terms in w, x, y and z177 double ****coeff; ///< Coefficients178 double ****coeffErr; ///< Error in coefficients179 char ****mask; ///< Coefficients mask180 }175 { 176 int nW, nX, nY, nZ; ///< Number of terms in w, x, y and z 177 double ****coeff; ///< Coefficients 178 double ****coeffErr; ///< Error in coefficients 179 char ****mask; ///< Coefficients mask 180 } 181 181 psDPolynomial4D; 182 182 … … 193 193 psDPolynomial4D *psDPolynomial4DAlloc( int nW, int nX, int nY, int nZ ///< Number of terms in w, x, y and z 194 194 ); 195 195 196 196 /** Evaluate 1D polynomial (double precision) */ 197 197 double … … 199 199 const psDPolynomial1D *myPoly ///< Coefficients for the polynomial 200 200 ); 201 201 202 202 /** Evaluate 2D polynomial (double precision) */ 203 203 double … … 206 206 const psDPolynomial2D *myPoly ///< Coefficients for the polynomial 207 207 ); 208 208 209 209 /** Evaluate 3D polynomial (double precision) */ 210 210 double … … 214 214 const psDPolynomial3D *myPoly ///< Coefficients for the polynomial 215 215 ); 216 216 217 217 /** Evaluate 4D polynomial (double precision) */ 218 218 double … … 223 223 const psDPolynomial4D *myPoly ///< Coefficients for the polynomial 224 224 ); 225 225 226 226 /* \} */ // End of MathGroup Functions 227 227 -
trunk/psLib/src/dataManip/psMatrix.c
r908 r1385 20 20 * @author Ross Harman, MHPCC 21 21 * 22 * @version $Revision: 1. 8$ $Name: not supported by cvs2svn $23 * @date $Date: 2004-0 6-08 01:57:52$22 * @version $Revision: 1.9 $ $Name: not supported by cvs2svn $ 23 * @date $Date: 2004-08-04 23:37:39 $ 24 24 * 25 25 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 475 475 PS_CHECK_ALLOC_VECTOR(outVector, inImage->numCols, inImage->type.type); 476 476 outVector->type.dimen = PS_DIMEN_TRANSV; 477 } else if(inImage->numCols == 1) { 478 // Create non-transposed column vector 479 PS_CHECK_ALLOC_VECTOR(outVector, inImage->numRows, inImage->type.type); 480 } else { 481 psError(__func__, "Image does not have dim with 1 col or 1 row: (%d x %d).", inImage->numRows, 482 inImage->numCols); 483 return outVector; 484 } 477 } else 478 if(inImage->numCols == 1) { 479 // Create non-transposed column vector 480 PS_CHECK_ALLOC_VECTOR(outVector, inImage->numRows, inImage->type.type); 481 } else { 482 psError(__func__, "Image does not have dim with 1 col or 1 row: (%d x %d).", inImage->numRows, 483 inImage->numCols); 484 return outVector; 485 } 485 486 486 487 PS_CHECK_NULL_VECTOR(outVector, outVector); … … 502 503 size = PSELEMTYPE_SIZEOF(inImage->type.type)*inImage->numRows; 503 504 504 } else if(outVector->type.dimen == PS_DIMEN_TRANSV) { 505 PS_CHECK_DIMEN_AND_TYPE(outVector, PS_DIMEN_TRANSV, outVector); 506 507 if(outVector->n == 0) { 508 outVector->n = inImage->numCols; 505 } else 506 if(outVector->type.dimen == PS_DIMEN_TRANSV) { 507 PS_CHECK_DIMEN_AND_TYPE(outVector, PS_DIMEN_TRANSV, outVector); 508 509 if(outVector->n == 0) { 510 outVector->n = inImage->numCols; 511 } 512 513 if(outVector->n != inImage->numCols) { 514 psError(__func__, "Image and vector sizes differ: (%d vs %d).", inImage->numCols, outVector->n); 515 return outVector; 516 } 517 518 size = PSELEMTYPE_SIZEOF(inImage->type.type)*inImage->numCols; 509 519 } 510 511 if(outVector->n != inImage->numCols) {512 psError(__func__, "Image and vector sizes differ: (%d vs %d).", inImage->numCols, outVector->n);513 return outVector;514 }515 516 size = PSELEMTYPE_SIZEOF(inImage->type.type)*inImage->numCols;517 }518 520 519 521 memcpy(outVector->data.V, inImage->data.V[0], size); … … 538 540 psError(__func__, "Image has more than 1 column: numCols = %d.", outImage->numCols); 539 541 return outImage; 540 } else if(outImage->numRows != inVector->n) { 541 psError(__func__, "Image and vector sizes differ: (%d vs %d).", outImage->numRows, inVector->n); 542 return outImage; 542 } else 543 if(outImage->numRows != inVector->n) { 544 psError(__func__, "Image and vector sizes differ: (%d vs %d).", outImage->numRows, inVector->n); 545 return outImage; 546 } 547 548 size = PSELEMTYPE_SIZEOF(outImage->type.type)*outImage->numRows; 549 550 } else 551 if(inVector->type.dimen == PS_DIMEN_TRANSV) { 552 PS_CHECK_DIMEN_AND_TYPE(inVector, PS_DIMEN_TRANSV, outImage); 553 PS_CHECK_SIZE_VECTOR(inVector, outImage); 554 PS_CHECK_ALLOC_IMAGE(outImage, inVector->n, 1, PS_TYPE_F64) 555 556 // More checks for PS_DIMEN_TRANSV 557 if(outImage->numRows > 1) { 558 psError(__func__, "Image has more than 1 row: numRows = %d.", outImage->numRows); 559 return outImage; 560 } else 561 if(outImage->numCols != inVector->n) { 562 psError(__func__, "Image and vector sizes differ: (%d vs %d).", outImage->numCols, inVector->n); 563 return outImage; 564 } 565 566 size = PSELEMTYPE_SIZEOF(outImage->type.type)*outImage->numCols; 543 567 } 544 545 size = PSELEMTYPE_SIZEOF(outImage->type.type)*outImage->numRows;546 547 } else if(inVector->type.dimen == PS_DIMEN_TRANSV) {548 PS_CHECK_DIMEN_AND_TYPE(inVector, PS_DIMEN_TRANSV, outImage);549 PS_CHECK_SIZE_VECTOR(inVector, outImage);550 PS_CHECK_ALLOC_IMAGE(outImage, inVector->n, 1, PS_TYPE_F64)551 552 // More checks for PS_DIMEN_TRANSV553 if(outImage->numRows > 1) {554 psError(__func__, "Image has more than 1 row: numRows = %d.", outImage->numRows);555 return outImage;556 } else if(outImage->numCols != inVector->n) {557 psError(__func__, "Image and vector sizes differ: (%d vs %d).", outImage->numCols, inVector->n);558 return outImage;559 }560 561 size = PSELEMTYPE_SIZEOF(outImage->type.type)*outImage->numCols;562 }563 568 564 569 PS_CHECK_NULL_IMAGE(outImage, outImage); -
trunk/psLib/src/dataManip/psMatrixVectorArithmetic.c
r1246 r1385 29 29 * @author Ross Harman, MHPCC 30 30 * 31 * @version $Revision: 1.1 8$ $Name: not supported by cvs2svn $32 * @date $Date: 2004-0 7-21 00:09:11$31 * @version $Revision: 1.19 $ $Name: not supported by cvs2svn $ 32 * @date $Date: 2004-08-04 23:37:39 $ 33 33 * 34 34 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 445 445 psError(__func__, ": Line %d - Vector contains zero elements"); 446 446 } 447 } else if(dim1 == PS_DIMEN_IMAGE) { 448 if(((psImage*)in1)->numCols==0 || ((psImage*)in1)->numRows==0) { 449 psError(__func__, ": Line %d - Image contains zero length row or cols"); 447 } else 448 if(dim1 == PS_DIMEN_IMAGE) { 449 if(((psImage*)in1)->numCols==0 || ((psImage*)in1)->numRows==0) { 450 psError(__func__, ": Line %d - Image contains zero length row or cols"); 451 } 450 452 } 451 }452 453 453 454 if(dim2 == PS_DIMEN_VECTOR) { … … 455 456 psError(__func__, ": Line %d - Vector contains zero elements"); 456 457 } 457 } else if(dim2 == PS_DIMEN_IMAGE) { 458 if(((psImage*)in2)->numCols==0 || ((psImage*)in2)->numRows==0) { 459 psError(__func__, ": Line %d - Image contains zero length row or cols"); 458 } else 459 if(dim2 == PS_DIMEN_IMAGE) { 460 if(((psImage*)in2)->numCols==0 || ((psImage*)in2)->numRows==0) { 461 psError(__func__, ": Line %d - Image contains zero length row or cols"); 462 } 460 463 } 461 }462 464 463 465 if(dim1 == PS_DIMEN_SCALAR) { 464 466 if(dim2 == PS_DIMEN_SCALAR) { 465 467 BINARY_OP(SCALAR,SCALAR,out,psType1,op,psType2); // scalar op scalar 466 } else if(dim2==PS_DIMEN_VECTOR || dim2==PS_DIMEN_TRANSV) { 467 BINARY_OP(SCALAR,VECTOR,out,psType1,op,psType2); // scalar op vector 468 } else if(dim2 == PS_DIMEN_IMAGE) { 469 BINARY_OP(SCALAR,IMAGE,out,psType1,op,psType2); // scalar op image 470 } else { 471 psError(__func__, ": Line %d - Invalid dimensionality for in2 arg: %d", __LINE__, dim2); 472 } 473 } else if(dim1==PS_DIMEN_VECTOR || dim1==PS_DIMEN_TRANSV) { 474 if(dim2 == PS_DIMEN_SCALAR) { 475 BINARY_OP(VECTOR,SCALAR,out,psType1,op,psType2); // vector op scalar 476 } else if(dim2==PS_DIMEN_VECTOR || dim2==PS_DIMEN_TRANSV) { 477 BINARY_OP(VECTOR,VECTOR,out,psType1,op,psType2); // vector op vector 478 } else if(dim2 == PS_DIMEN_IMAGE) { 479 BINARY_OP(VECTOR,IMAGE,out,psType1,op,psType2); // vector op image 480 } else { 481 psError(__func__, ": Line %d - Invalid dimensionality for in2 arg: %d", __LINE__, dim2); 482 } 483 } else if(dim1 == PS_DIMEN_IMAGE) { 484 if(dim2 == PS_DIMEN_SCALAR) { 485 BINARY_OP(IMAGE,SCALAR,out,psType1,op,psType2); // image op scalar 486 } else if(dim2==PS_DIMEN_VECTOR || dim2==PS_DIMEN_TRANSV) { 487 BINARY_OP(IMAGE,VECTOR,out,psType1,op,psType2); // image op vector 488 } else if(dim2 == PS_DIMEN_IMAGE) { 489 BINARY_OP(IMAGE,IMAGE,out,psType1,op,psType2); // image op image 490 } else { 491 psError(__func__, ": Line %d - Invalid dimensionality for in2 arg: %d", __LINE__, dim2); 492 } 493 } else { 494 psError(__func__, ": Line %d - Invalid dimensionality for in1 arg: %d", __LINE__, dim1); 495 } 468 } else 469 if(dim2==PS_DIMEN_VECTOR || dim2==PS_DIMEN_TRANSV) { 470 BINARY_OP(SCALAR,VECTOR,out,psType1,op,psType2); // scalar op vector 471 } else 472 if(dim2 == PS_DIMEN_IMAGE) { 473 BINARY_OP(SCALAR,IMAGE,out,psType1,op,psType2); // scalar op image 474 } else { 475 psError(__func__, ": Line %d - Invalid dimensionality for in2 arg: %d", __LINE__, dim2); 476 } 477 } else 478 if(dim1==PS_DIMEN_VECTOR || dim1==PS_DIMEN_TRANSV) { 479 if(dim2 == PS_DIMEN_SCALAR) { 480 BINARY_OP(VECTOR,SCALAR,out,psType1,op,psType2); // vector op scalar 481 } else 482 if(dim2==PS_DIMEN_VECTOR || dim2==PS_DIMEN_TRANSV) { 483 BINARY_OP(VECTOR,VECTOR,out,psType1,op,psType2); // vector op vector 484 } else 485 if(dim2 == PS_DIMEN_IMAGE) { 486 BINARY_OP(VECTOR,IMAGE,out,psType1,op,psType2); // vector op image 487 } else { 488 psError(__func__, ": Line %d - Invalid dimensionality for in2 arg: %d", __LINE__, dim2); 489 } 490 } else 491 if(dim1 == PS_DIMEN_IMAGE) { 492 if(dim2 == PS_DIMEN_SCALAR) { 493 BINARY_OP(IMAGE,SCALAR,out,psType1,op,psType2); // image op scalar 494 } else 495 if(dim2==PS_DIMEN_VECTOR || dim2==PS_DIMEN_TRANSV) { 496 BINARY_OP(IMAGE,VECTOR,out,psType1,op,psType2); // image op vector 497 } else 498 if(dim2 == PS_DIMEN_IMAGE) { 499 BINARY_OP(IMAGE,IMAGE,out,psType1,op,psType2); // image op image 500 } else { 501 psError(__func__, ": Line %d - Invalid dimensionality for in2 arg: %d", __LINE__, dim2); 502 } 503 } else { 504 psError(__func__, ": Line %d - Invalid dimensionality for in1 arg: %d", __LINE__, dim1); 505 } 496 506 497 507 return out; … … 748 758 psError(__func__, ": Line %d - Vector contains zero elements"); 749 759 } 750 } else if(dimIn == PS_DIMEN_IMAGE) { 751 if(((psImage*)in)->numCols==0 || ((psImage*)in)->numRows==0) { 752 psError(__func__, ": Line %d - Image contains zero length row or cols"); 760 } else 761 if(dimIn == PS_DIMEN_IMAGE) { 762 if(((psImage*)in)->numCols==0 || ((psImage*)in)->numRows==0) { 763 psError(__func__, ": Line %d - Image contains zero length row or cols"); 764 } 753 765 } 754 }755 766 756 767 if(dimOut == PS_DIMEN_VECTOR) { … … 758 769 psError(__func__, ": Line %d - Vector contains zero elements"); 759 770 } 760 } else if(dimOut == PS_DIMEN_IMAGE) { 761 if(((psImage*)out)->numCols==0 || ((psImage*)out)->numRows==0) { 762 psError(__func__, ": Line %d - Image contains zero length row or cols"); 771 } else 772 if(dimOut == PS_DIMEN_IMAGE) { 773 if(((psImage*)out)->numCols==0 || ((psImage*)out)->numRows==0) { 774 psError(__func__, ": Line %d - Image contains zero length row or cols"); 775 } 763 776 } 764 }765 777 766 778 if(dimIn == PS_DIMEN_SCALAR) { 767 779 UNARY_OP(SCALAR,out,psTypeIn,op); // scalar 768 } else if(dimIn==PS_DIMEN_VECTOR || dimIn==PS_DIMEN_TRANSV) { 769 UNARY_OP(VECTOR,out,psTypeIn,op); // vector 770 } else if(dimIn == PS_DIMEN_IMAGE) { 771 UNARY_OP(IMAGE,out,psTypeIn,op); // image 772 } else { 773 psError(__func__, ": Line %d - Invalid dimensionality for in arg: %d", __LINE__, dimIn); 774 } 780 } else 781 if(dimIn==PS_DIMEN_VECTOR || dimIn==PS_DIMEN_TRANSV) { 782 UNARY_OP(VECTOR,out,psTypeIn,op); // vector 783 } else 784 if(dimIn == PS_DIMEN_IMAGE) { 785 UNARY_OP(IMAGE,out,psTypeIn,op); // image 786 } else { 787 psError(__func__, ": Line %d - Invalid dimensionality for in arg: %d", __LINE__, dimIn); 788 } 775 789 776 790 return out; -
trunk/psLib/src/dataManip/psMinimize.c
r1345 r1385 9 9 * @author George Gusciora, MHPCC 10 10 * 11 * @version $Revision: 1.2 5$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-0 7-30 00:39:14$11 * @version $Revision: 1.26 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-08-04 23:37:39 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/dataManip/psStats.c
r1361 r1385 36 36 unsigned int maskVal, 37 37 psStats *stats ); 38 38 39 39 /** Preprocessor macro to generate error on an incorrect type */ 40 40 #define PS_CHECK_VECTOR_TYPE(NAME, TYPE) \ 41 41 if (NAME->type.type != TYPE) { \ 42 psError(__func__,"Invalid operation: %s has incorrect type.", #NAME); \43 }44 42 psError(__func__,"Invalid operation: %s has incorrect type.", #NAME); \ 43 } 44 45 45 /** Preprocessor macro to generate error on a NULL vector */ 46 46 #define PS_CHECK_NULL_VECTOR(NAME) \ 47 47 if (NAME == NULL || NAME->data.V == NULL) { \ 48 psError(__func__,"Invalid operation: %s or its data is NULL.", #NAME); \49 }50 48 psError(__func__,"Invalid operation: %s or its data is NULL.", #NAME); \ 49 } 50 51 51 /** Preprocessor macro to generate error for zero length vector */ 52 52 #define PS_CHECK_EMPTY_VECTOR(NAME) \ 53 53 if (NAME->n < 1) { \ 54 psError(__func__,"Invalid operation: %s has zero n value.", #NAME); \55 }56 54 psError(__func__,"Invalid operation: %s has zero n value.", #NAME); \ 55 } 56 57 57 /** Preprocessor macro to generate error on differing size vectors */ 58 58 #define PS_CHECK_VECTOR_SIZE_EQUAL(VEC1, VEC2) \ 59 59 if (VEC1->n != VEC2->n) { \ 60 psError(__func__,"Vector %s has size %d, Vector %s has size %d.", #VEC1, VEC1->n, #VEC2, VEC2->n); \61 }62 60 psError(__func__,"Vector %s has size %d, Vector %s has size %d.", #VEC1, VEC1->n, #VEC2, VEC2->n); \ 61 } 62 63 63 #define PS_PRINT_VECTOR(NAME) \ 64 64 for (int my_i=0;my_i<NAME->n;my_i++) { \ 65 printf("%s->data.F32[%d] is %f\n", #NAME, my_i, NAME->data.F32[my_i]); \66 } \65 printf("%s->data.F32[%d] is %f\n", #NAME, my_i, NAME->data.F32[my_i]); \ 66 } \ 67 67 printf("\n"); \ 68 68 … … 92 92 switch ( stats->options & 93 93 ~ ( PS_STAT_USE_RANGE | PS_STAT_USE_BINSIZE | PS_STAT_ROBUST_FOR_SAMPLE ) ) { 94 case PS_STAT_SAMPLE_MEAN:95 *value = stats->sampleMean;96 return true;97 98 case PS_STAT_SAMPLE_MEDIAN:99 *value = stats->sampleMedian;100 return true;101 102 case PS_STAT_SAMPLE_STDEV:103 *value = stats->sampleStdev;104 return true;105 106 case PS_STAT_ROBUST_MEAN:107 *value = stats->robustMean;108 return true;109 110 case PS_STAT_ROBUST_MEDIAN:111 *value = stats->robustMedian;112 return true;113 114 case PS_STAT_ROBUST_MODE:115 *value = stats->robustMode;116 return true;117 118 case PS_STAT_ROBUST_STDEV:119 *value = stats->robustStdev;120 return true;121 122 case PS_STAT_CLIPPED_MEAN:123 *value = stats->clippedMean;124 return true;125 126 case PS_STAT_CLIPPED_STDEV:127 *value = stats->clippedStdev;128 return true;129 130 case PS_STAT_MAX:131 *value = stats->max;132 return true;133 134 case PS_STAT_MIN:135 *value = stats->min;136 return true;137 138 default:139 return false;140 }94 case PS_STAT_SAMPLE_MEAN: 95 *value = stats->sampleMean; 96 return true; 97 98 case PS_STAT_SAMPLE_MEDIAN: 99 *value = stats->sampleMedian; 100 return true; 101 102 case PS_STAT_SAMPLE_STDEV: 103 *value = stats->sampleStdev; 104 return true; 105 106 case PS_STAT_ROBUST_MEAN: 107 *value = stats->robustMean; 108 return true; 109 110 case PS_STAT_ROBUST_MEDIAN: 111 *value = stats->robustMedian; 112 return true; 113 114 case PS_STAT_ROBUST_MODE: 115 *value = stats->robustMode; 116 return true; 117 118 case PS_STAT_ROBUST_STDEV: 119 *value = stats->robustStdev; 120 return true; 121 122 case PS_STAT_CLIPPED_MEAN: 123 *value = stats->clippedMean; 124 return true; 125 126 case PS_STAT_CLIPPED_STDEV: 127 *value = stats->clippedStdev; 128 return true; 129 130 case PS_STAT_MAX: 131 *value = stats->max; 132 return true; 133 134 case PS_STAT_MIN: 135 *value = stats->min; 136 return true; 137 138 default: 139 return false; 140 } 141 141 } 142 142 … … 153 153 { 154 154 int i = 0; // Loop index variable. 155 155 156 156 for ( i = 0;i < myVector->n;i++ ) { 157 if ( maskVector != NULL )158 printf( "Element %d is %f (mask is %d)\n", i, myVector->data.F32[ i ], maskVector->data.U8[ i ] );159 else160 printf( "Element %d is %f\n", i, myVector->data.F32[ i ] );161 }157 if ( maskVector != NULL ) 158 printf( "Element %d is %f (mask is %d)\n", i, myVector->data.F32[ i ], maskVector->data.U8[ i ] ); 159 else 160 printf( "Element %d is %f\n", i, myVector->data.F32[ i ] ); 161 } 162 162 } 163 163 … … 204 204 float rangeMin = 0.0; // Exclude data below this 205 205 float rangeMax = 0.0; // Exclude date above this 206 206 207 207 // If PS_STAT_USE_RANGE is requested, then we enter a slightly different 208 208 // loop. 209 209 if ( stats->options & PS_STAT_USE_RANGE ) { 210 rangeMin = stats->min; 211 rangeMax = stats->max; 212 if ( maskVector != NULL ) { 213 for ( i = 0;i < myVector->n;i++ ) { 214 // Check if the data is with the specified range 215 if ( !( maskVal & maskVector->data.U8[ i ] ) && 216 ( rangeMin <= myVector->data.F32[ i ] ) && 217 ( myVector->data.F32[ i ] <= rangeMax ) ) { 218 mean += myVector->data.F32[ i ]; 219 count++; 220 } 221 } 222 mean /= ( float ) count; 223 } else { 224 for ( i = 0;i < myVector->n;i++ ) { 225 if ( ( rangeMin <= myVector->data.F32[ i ] ) && 226 ( myVector->data.F32[ i ] <= rangeMax ) ) { 227 mean += myVector->data.F32[ i ]; 228 count++; 229 } 230 } 231 mean /= ( float ) count; 232 } 210 rangeMin = stats->min; 211 rangeMax = stats->max; 212 if ( maskVector != NULL ) { 213 for ( i = 0;i < myVector->n;i++ ) { 214 // Check if the data is with the specified range 215 if ( !( maskVal & maskVector->data.U8[ i ] ) && 216 ( rangeMin <= myVector->data.F32[ i ] ) && 217 ( myVector->data.F32[ i ] <= rangeMax ) ) { 218 mean += myVector->data.F32[ i ]; 219 count++; 220 } 221 } 222 mean /= ( float ) count; 233 223 } else { 234 if ( maskVector != NULL ) { 235 for ( i = 0;i < myVector->n;i++ ) { 236 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 237 mean += myVector->data.F32[ i ]; 238 count++; 239 } 240 } 241 mean /= ( float ) count; 242 } else { 243 for ( i = 0;i < myVector->n;i++ ) { 244 mean += myVector->data.F32[ i ]; 245 } 246 mean /= ( float ) myVector->n; 247 } 248 } 249 224 for ( i = 0;i < myVector->n;i++ ) { 225 if ( ( rangeMin <= myVector->data.F32[ i ] ) && 226 ( myVector->data.F32[ i ] <= rangeMax ) ) { 227 mean += myVector->data.F32[ i ]; 228 count++; 229 } 230 } 231 mean /= ( float ) count; 232 } 233 } else { 234 if ( maskVector != NULL ) { 235 for ( i = 0;i < myVector->n;i++ ) { 236 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 237 mean += myVector->data.F32[ i ]; 238 count++; 239 } 240 } 241 mean /= ( float ) count; 242 } else { 243 for ( i = 0;i < myVector->n;i++ ) { 244 mean += myVector->data.F32[ i ]; 245 } 246 mean /= ( float ) myVector->n; 247 } 248 } 249 250 250 stats->sampleMean = mean; 251 251 } … … 271 271 float rangeMin = 0.0; // Exclude data below this 272 272 float rangeMax = 0.0; // Exclude date above this 273 273 274 274 // If PS_STAT_USE_RANGE is requested, then we enter a different loop. 275 275 if ( stats->options & PS_STAT_USE_RANGE ) { 276 rangeMin = stats->min; 277 rangeMax = stats->max; 278 if ( maskVector != NULL ) { 279 for ( i = 0;i < myVector->n;i++ ) { 280 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 281 if ( ( myVector->data.F32[ i ] > max ) && 282 ( rangeMin <= myVector->data.F32[ i ] ) && 283 ( myVector->data.F32[ i ] <= rangeMax ) ) { 284 max = myVector->data.F32[ i ]; 285 } 286 } 287 } 288 } else { 289 for ( i = 0;i < myVector->n;i++ ) { 290 if ( ( myVector->data.F32[ i ] > max ) && 291 ( rangeMin <= myVector->data.F32[ i ] ) && 292 ( myVector->data.F32[ i ] <= rangeMax ) ) { 293 max = myVector->data.F32[ i ]; 294 } 295 } 296 } 276 rangeMin = stats->min; 277 rangeMax = stats->max; 278 if ( maskVector != NULL ) { 279 for ( i = 0;i < myVector->n;i++ ) { 280 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 281 if ( ( myVector->data.F32[ i ] > max ) && 282 ( rangeMin <= myVector->data.F32[ i ] ) && 283 ( myVector->data.F32[ i ] <= rangeMax ) ) { 284 max = myVector->data.F32[ i ]; 285 } 286 } 287 } 297 288 } else { 298 if ( maskVector != NULL ) { 299 for ( i = 0;i < myVector->n;i++ ) { 300 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 301 if ( myVector->data.F32[ i ] > max ) { 302 max = myVector->data.F32[ i ]; 303 } 304 } 305 } 306 } else { 307 for ( i = 0;i < myVector->n;i++ ) { 308 if ( myVector->data.F32[ i ] > max ) { 309 max = myVector->data.F32[ i ]; 310 } 311 } 312 } 313 } 314 289 for ( i = 0;i < myVector->n;i++ ) { 290 if ( ( myVector->data.F32[ i ] > max ) && 291 ( rangeMin <= myVector->data.F32[ i ] ) && 292 ( myVector->data.F32[ i ] <= rangeMax ) ) { 293 max = myVector->data.F32[ i ]; 294 } 295 } 296 } 297 } else { 298 if ( maskVector != NULL ) { 299 for ( i = 0;i < myVector->n;i++ ) { 300 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 301 if ( myVector->data.F32[ i ] > max ) { 302 max = myVector->data.F32[ i ]; 303 } 304 } 305 } 306 } else { 307 for ( i = 0;i < myVector->n;i++ ) { 308 if ( myVector->data.F32[ i ] > max ) { 309 max = myVector->data.F32[ i ]; 310 } 311 } 312 } 313 } 314 315 315 stats->max = max; 316 316 } … … 336 336 float rangeMin = 0.0; // Exclude data below this 337 337 float rangeMax = 0.0; // Exclude date above this 338 338 339 339 if ( stats->options & PS_STAT_USE_RANGE ) { 340 rangeMin = stats->min; 341 rangeMax = stats->max; 342 if ( maskVector != NULL ) { 343 for ( i = 0;i < myVector->n;i++ ) { 344 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 345 if ( ( myVector->data.F32[ i ] < min ) && 346 ( rangeMin <= myVector->data.F32[ i ] ) && 347 ( myVector->data.F32[ i ] <= rangeMax ) ) { 348 min = myVector->data.F32[ i ]; 349 } 350 } 351 } 352 } else { 353 for ( i = 0;i < myVector->n;i++ ) { 354 if ( ( myVector->data.F32[ i ] < min ) && 355 ( rangeMin <= myVector->data.F32[ i ] ) && 356 ( myVector->data.F32[ i ] <= rangeMax ) ) { 357 min = myVector->data.F32[ i ]; 358 } 359 } 360 } 340 rangeMin = stats->min; 341 rangeMax = stats->max; 342 if ( maskVector != NULL ) { 343 for ( i = 0;i < myVector->n;i++ ) { 344 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 345 if ( ( myVector->data.F32[ i ] < min ) && 346 ( rangeMin <= myVector->data.F32[ i ] ) && 347 ( myVector->data.F32[ i ] <= rangeMax ) ) { 348 min = myVector->data.F32[ i ]; 349 } 350 } 351 } 361 352 } else { 362 if ( maskVector != NULL ) { 363 for ( i = 0;i < myVector->n;i++ ) { 364 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 365 if ( myVector->data.F32[ i ] < min ) { 366 min = myVector->data.F32[ i ]; 367 } 368 } 369 } 370 } else { 371 for ( i = 0;i < myVector->n;i++ ) { 372 if ( myVector->data.F32[ i ] < min ) { 373 min = myVector->data.F32[ i ]; 374 } 375 } 376 } 377 } 378 353 for ( i = 0;i < myVector->n;i++ ) { 354 if ( ( myVector->data.F32[ i ] < min ) && 355 ( rangeMin <= myVector->data.F32[ i ] ) && 356 ( myVector->data.F32[ i ] <= rangeMax ) ) { 357 min = myVector->data.F32[ i ]; 358 } 359 } 360 } 361 } else { 362 if ( maskVector != NULL ) { 363 for ( i = 0;i < myVector->n;i++ ) { 364 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 365 if ( myVector->data.F32[ i ] < min ) { 366 min = myVector->data.F32[ i ]; 367 } 368 } 369 } 370 } else { 371 for ( i = 0;i < myVector->n;i++ ) { 372 if ( myVector->data.F32[ i ] < min ) { 373 min = myVector->data.F32[ i ]; 374 } 375 } 376 } 377 } 378 379 379 stats->min = min; 380 380 } … … 401 401 float rangeMin = 0.0; // Exclude data below this 402 402 float rangeMax = 0.0; // Exclude date above this 403 403 404 404 if ( stats->options & PS_STAT_USE_RANGE ) { 405 rangeMin = stats->min; 406 rangeMax = stats->max; 407 if ( maskVector != NULL ) { 408 for ( i = 0;i < myVector->n;i++ ) { 409 if ( !( maskVal & maskVector->data.U8[ i ] ) && 410 ( rangeMin <= myVector->data.F32[ i ] ) && 411 ( myVector->data.F32[ i ] <= rangeMax ) ) { 412 numData++; 413 } 414 } 415 } else { 416 for ( i = 0;i < myVector->n;i++ ) { 417 if ( ( rangeMin <= myVector->data.F32[ i ] ) && 418 ( myVector->data.F32[ i ] <= rangeMax ) ) { 419 numData++; 420 } 421 } 422 } 405 rangeMin = stats->min; 406 rangeMax = stats->max; 407 if ( maskVector != NULL ) { 408 for ( i = 0;i < myVector->n;i++ ) { 409 if ( !( maskVal & maskVector->data.U8[ i ] ) && 410 ( rangeMin <= myVector->data.F32[ i ] ) && 411 ( myVector->data.F32[ i ] <= rangeMax ) ) { 412 numData++; 413 } 414 } 423 415 } else { 424 rangeMin = stats->min; 425 rangeMax = stats->max; 426 if ( maskVector != NULL ) { 427 for ( i = 0;i < myVector->n;i++ ) { 428 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 429 numData++; 430 } 431 } 432 } else { 433 numData = myVector->n; 434 } 435 } 416 for ( i = 0;i < myVector->n;i++ ) { 417 if ( ( rangeMin <= myVector->data.F32[ i ] ) && 418 ( myVector->data.F32[ i ] <= rangeMax ) ) { 419 numData++; 420 } 421 } 422 } 423 } else { 424 rangeMin = stats->min; 425 rangeMax = stats->max; 426 if ( maskVector != NULL ) { 427 for ( i = 0;i < myVector->n;i++ ) { 428 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 429 numData++; 430 } 431 } 432 } else { 433 numData = myVector->n; 434 } 435 } 436 436 return ( numData ); 437 437 } … … 462 462 float rangeMin = 0.0; // Exclude data below this 463 463 float rangeMax = 0.0; // Exclude date above this 464 465 464 465 466 466 // Determine if the number of data points exceed a threshold which will 467 467 // cause to generate robust stats, as opposed to exact stats. … … 488 488 } 489 489 */ 490 490 491 491 // Determine how many data points fit inside this min/max range 492 492 // and are not masked, IF the maskVector is not NULL> 493 493 nValues = p_psVectorNValues( myVector, maskVector, maskVal, stats ); 494 494 495 495 // Allocate temporary vectors for the data. 496 496 unsortedVector = psVectorAlloc( nValues, PS_TYPE_F32 ); 497 497 unsortedVector->n = unsortedVector->nalloc; 498 498 499 499 sortedVector = psVectorAlloc( nValues, PS_TYPE_F32 ); 500 500 sortedVector->n = sortedVector->nalloc; 501 501 502 502 // Determine if we must only use data points within a min/max range. 503 503 if ( stats->options & PS_STAT_USE_RANGE ) { 504 rangeMin = stats->min; 505 rangeMax = stats->max; 506 507 // Store all non-masked data points within the min/max range 508 // into the temporary vectors. 509 count = 0; 510 if ( maskVector != NULL ) { 511 for ( i = 0;i < myVector->n;i++ ) { 512 if ( !( maskVal & maskVector->data.U8[ i ] ) && 513 ( rangeMin <= myVector->data.F32[ i ] ) && 514 ( myVector->data.F32[ i ] <= rangeMax ) ) { 515 unsortedVector->data.F32[ count++ ] = maskVector->data.F32[ i ]; 516 } 517 } 518 } else { 519 for ( i = 0;i < myVector->n;i++ ) { 520 if ( ( rangeMin <= myVector->data.F32[ i ] ) && 521 ( myVector->data.F32[ i ] <= rangeMax ) ) { 522 unsortedVector->data.F32[ count++ ] = myVector->data.F32[ i ]; 523 } 524 } 525 } 504 rangeMin = stats->min; 505 rangeMax = stats->max; 506 507 // Store all non-masked data points within the min/max range 508 // into the temporary vectors. 509 count = 0; 510 if ( maskVector != NULL ) { 511 for ( i = 0;i < myVector->n;i++ ) { 512 if ( !( maskVal & maskVector->data.U8[ i ] ) && 513 ( rangeMin <= myVector->data.F32[ i ] ) && 514 ( myVector->data.F32[ i ] <= rangeMax ) ) { 515 unsortedVector->data.F32[ count++ ] = maskVector->data.F32[ i ]; 516 } 517 } 526 518 } else { 527 // Store all non-masked data points into the temporary vectors. 528 count = 0; 529 if ( maskVector != NULL ) { 530 for ( i = 0;i < myVector->n;i++ ) { 531 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 532 unsortedVector->data.F32[ count++ ] = myVector->data.F32[ i ]; 533 } 534 } 535 } else { 536 for ( i = 0;i < myVector->n;i++ ) { 537 unsortedVector->data.F32[ i ] = myVector->data.F32[ i ]; 538 } 539 } 540 } 519 for ( i = 0;i < myVector->n;i++ ) { 520 if ( ( rangeMin <= myVector->data.F32[ i ] ) && 521 ( myVector->data.F32[ i ] <= rangeMax ) ) { 522 unsortedVector->data.F32[ count++ ] = myVector->data.F32[ i ]; 523 } 524 } 525 } 526 } else { 527 // Store all non-masked data points into the temporary vectors. 528 count = 0; 529 if ( maskVector != NULL ) { 530 for ( i = 0;i < myVector->n;i++ ) { 531 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 532 unsortedVector->data.F32[ count++ ] = myVector->data.F32[ i ]; 533 } 534 } 535 } else { 536 for ( i = 0;i < myVector->n;i++ ) { 537 unsortedVector->data.F32[ i ] = myVector->data.F32[ i ]; 538 } 539 } 540 } 541 541 // Sort the temporary vectors. 542 542 psVectorSort( sortedVector, unsortedVector ); 543 543 544 544 // Calculate the median exactly. 545 545 // XXX: Is this the correct action? 546 546 if ( 0 == ( nValues % 2 ) ) { 547 stats->sampleMedian = 0.5 * ( sortedVector->data.F32[ ( nValues / 2 ) - 1 ] +548 sortedVector->data.F32[ nValues / 2 ] );549 } else {550 stats->sampleMedian = sortedVector->data.F32[ nValues / 2 ];551 }552 547 stats->sampleMedian = 0.5 * ( sortedVector->data.F32[ ( nValues / 2 ) - 1 ] + 548 sortedVector->data.F32[ nValues / 2 ] ); 549 } else { 550 stats->sampleMedian = sortedVector->data.F32[ nValues / 2 ]; 551 } 552 553 553 // Free the temporary data structures. 554 554 psFree( unsortedVector ); … … 577 577 float gaussianCoefs[ 1 + ( 2 * GAUSS_WIDTH ) ]; // The Gaussian Coefficients 578 578 psVector *smooth = psVectorAlloc( robustHistogram->nums->n, PS_TYPE_F32 ); 579 579 580 580 for ( i = 0;i < ( 1 + ( 2 * GAUSS_WIDTH ) );i++ ) { 581 if ( fabs( sigma ) >= FLT_EPSILON ) {582 // If sigma does not equal zero, then we use Gaussian smoothing.583 #ifdef DARWIN584 denom = ( float ) sqrt( 2.0 * M_PI * sigma * sigma );585 #else586 587 denom = sqrtf( 2.0 * M_PI * sigma * sigma );588 #endif589 590 expo = - ( float ) ( ( i - GAUSS_WIDTH ) * ( i - GAUSS_WIDTH ) );591 expo /= ( 2.0 * sigma * sigma );592 gaussianCoefs[ i ] = exp( expo / denom );593 594 // NOTE: Gaussian smoothing just isn't working with low sigma595 // values. The problem is that the Gaussian coefficients are596 // all zero, except for the middle coefficient, which is exactly597 // one. Therefore, I'm using boxcar smoothing.598 gaussianCoefs[ i ] = 1.0 / ( 1.0 + ( 2.0 * ( float ) GAUSS_WIDTH ) );599 // printf("gaussianCoefs[%d] is %f\n", i, gaussianCoefs[i]);600 } else {601 /* If sigma equals zero (all pixels have the same value)602 * the above code will divide by zero. Therefore, we don't need603 * to smooth the data.604 */605 for ( i = 0;i < robustHistogram->nums->n;i++ ) {606 smooth->data.F32[ i ] = ( float ) robustHistogram->nums->data.S32[ i ];607 }608 return ( smooth );609 }610 }611 581 if ( fabs( sigma ) >= FLT_EPSILON ) { 582 // If sigma does not equal zero, then we use Gaussian smoothing. 583 #ifdef DARWIN 584 denom = ( float ) sqrt( 2.0 * M_PI * sigma * sigma ); 585 #else 586 587 denom = sqrtf( 2.0 * M_PI * sigma * sigma ); 588 #endif 589 590 expo = - ( float ) ( ( i - GAUSS_WIDTH ) * ( i - GAUSS_WIDTH ) ); 591 expo /= ( 2.0 * sigma * sigma ); 592 gaussianCoefs[ i ] = exp( expo / denom ); 593 594 // NOTE: Gaussian smoothing just isn't working with low sigma 595 // values. The problem is that the Gaussian coefficients are 596 // all zero, except for the middle coefficient, which is exactly 597 // one. Therefore, I'm using boxcar smoothing. 598 gaussianCoefs[ i ] = 1.0 / ( 1.0 + ( 2.0 * ( float ) GAUSS_WIDTH ) ); 599 // printf("gaussianCoefs[%d] is %f\n", i, gaussianCoefs[i]); 600 } else { 601 /* If sigma equals zero (all pixels have the same value) 602 * the above code will divide by zero. Therefore, we don't need 603 * to smooth the data. 604 */ 605 for ( i = 0;i < robustHistogram->nums->n;i++ ) { 606 smooth->data.F32[ i ] = ( float ) robustHistogram->nums->data.S32[ i ]; 607 } 608 return ( smooth ); 609 } 610 } 611 612 612 // Perform the actual smoothing. 613 613 for ( i = 0;i < robustHistogram->nums->n;i++ ) { 614 smooth->data.F32[ i ] = 0.0;615 for ( j = -GAUSS_WIDTH;j <= + GAUSS_WIDTH;j++ ) {616 if ( ( ( j + i ) >= 0 ) && ( ( j + i ) < smooth->n ) ) {617 smooth->data.F32[ i ] += ( gaussianCoefs[ j + GAUSS_WIDTH ] *618 ( float ) robustHistogram->nums->data.S32[ j + i ] );619 }620 }621 }614 smooth->data.F32[ i ] = 0.0; 615 for ( j = -GAUSS_WIDTH;j <= + GAUSS_WIDTH;j++ ) { 616 if ( ( ( j + i ) >= 0 ) && ( ( j + i ) < smooth->n ) ) { 617 smooth->data.F32[ i ] += ( gaussianCoefs[ j + GAUSS_WIDTH ] * 618 ( float ) robustHistogram->nums->data.S32[ j + i ] ); 619 } 620 } 621 } 622 622 return ( smooth ); 623 623 } … … 646 646 float rangeMin = 0.0; // Exclude data below this 647 647 float rangeMax = 0.0; // Exclude date above this 648 648 649 649 // Determine how many data points fit inside this min/max range 650 650 // and are not maxed, IF the maskVector is not NULL> 651 651 nValues = p_psVectorNValues( myVector, maskVector, maskVal, stats ); 652 652 653 653 // Allocate temporary vectors for the data. 654 654 unsortedVector = psVectorAlloc( nValues, PS_TYPE_F32 ); … … 656 656 sortedVector = psVectorAlloc( nValues, PS_TYPE_F32 ); 657 657 sortedVector->n = sortedVector->nalloc; 658 658 659 659 // Determine if we must only use data points within a min/max range. 660 660 if ( stats->options & PS_STAT_USE_RANGE ) { 661 rangeMin = stats->min; 662 rangeMax = stats->max; 663 // Store all non-masked data points within the min/max range 664 // into the temporary vectors. 665 count = 0; 666 if ( maskVector != NULL ) { 667 for ( i = 0;i < myVector->n;i++ ) { 668 if ( !( maskVal & maskVector->data.U8[ i ] ) && 669 ( rangeMin <= myVector->data.F32[ i ] ) && 670 ( myVector->data.F32[ i ] <= rangeMax ) ) { 671 unsortedVector->data.F32[ count++ ] = myVector->data.F32[ i ]; 672 } 673 } 674 } else { 675 for ( i = 0;i < myVector->n;i++ ) { 676 if ( ( rangeMin <= myVector->data.F32[ i ] ) && 677 ( myVector->data.F32[ i ] <= rangeMax ) ) { 678 unsortedVector->data.F32[ count++ ] = myVector->data.F32[ i ]; 679 } 680 } 681 } 661 rangeMin = stats->min; 662 rangeMax = stats->max; 663 // Store all non-masked data points within the min/max range 664 // into the temporary vectors. 665 count = 0; 666 if ( maskVector != NULL ) { 667 for ( i = 0;i < myVector->n;i++ ) { 668 if ( !( maskVal & maskVector->data.U8[ i ] ) && 669 ( rangeMin <= myVector->data.F32[ i ] ) && 670 ( myVector->data.F32[ i ] <= rangeMax ) ) { 671 unsortedVector->data.F32[ count++ ] = myVector->data.F32[ i ]; 672 } 673 } 682 674 } else { 683 // Store all non-masked data points into the temporary vectors. 684 count = 0; 685 if ( maskVector != NULL ) { 686 for ( i = 0;i < myVector->n;i++ ) { 687 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 688 unsortedVector->data.F32[ count++ ] = myVector->data.F32[ i ]; 689 } 690 } 691 } else { 692 for ( i = 0;i < myVector->n;i++ ) { 693 unsortedVector->data.F32[ i ] = myVector->data.F32[ i ]; 694 } 695 } 696 } 697 675 for ( i = 0;i < myVector->n;i++ ) { 676 if ( ( rangeMin <= myVector->data.F32[ i ] ) && 677 ( myVector->data.F32[ i ] <= rangeMax ) ) { 678 unsortedVector->data.F32[ count++ ] = myVector->data.F32[ i ]; 679 } 680 } 681 } 682 } else { 683 // Store all non-masked data points into the temporary vectors. 684 count = 0; 685 if ( maskVector != NULL ) { 686 for ( i = 0;i < myVector->n;i++ ) { 687 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 688 unsortedVector->data.F32[ count++ ] = myVector->data.F32[ i ]; 689 } 690 } 691 } else { 692 for ( i = 0;i < myVector->n;i++ ) { 693 unsortedVector->data.F32[ i ] = myVector->data.F32[ i ]; 694 } 695 } 696 } 697 698 698 // Sort the temporary vectors. 699 699 psVectorSort( sortedVector, unsortedVector ); 700 700 701 701 // Calculate the quartile points exactly. 702 702 stats->sampleUQ = sortedVector->data.F32[ 3 * ( nValues / 4 ) ]; 703 703 stats->sampleLQ = sortedVector->data.F32[ nValues / 4 ]; 704 704 705 705 // Free the temporary data structures. 706 706 psFree( unsortedVector ); … … 735 735 float rangeMin = 0.0; // Exclude data below this 736 736 float rangeMax = 0.0; // Exclude date above this 737 737 738 738 // This procedure requires the mean. If it has not been already 739 739 // calculated, then call p_psVectorSampleMean() 740 740 if ( 0 != isnan( stats->sampleMean ) ) { 741 p_psVectorSampleMean( myVector, maskVector, maskVal, stats );742 }741 p_psVectorSampleMean( myVector, maskVector, maskVal, stats ); 742 } 743 743 mean = stats->sampleMean; 744 744 745 745 if ( stats->options & PS_STAT_USE_RANGE ) { 746 if ( maskVector != NULL ) { 747 for ( i = 0;i < myVector->n;i++ ) { 748 if ( !( maskVal & maskVector->data.U8[ i ] ) && 749 ( rangeMin <= myVector->data.F32[ i ] ) && 750 ( myVector->data.F32[ i ] <= rangeMax ) ) { 751 diff = myVector->data.F32[ i ] - mean; 752 sumSquares += ( diff * diff ); 753 sumDiffs += diff; 754 countInt++; 755 } 756 } 757 } else { 758 for ( i = 0;i < myVector->n;i++ ) { 759 if ( ( rangeMin <= myVector->data.F32[ i ] ) && 760 ( myVector->data.F32[ i ] <= rangeMax ) ) { 761 diff = myVector->data.F32[ i ] - mean; 762 sumSquares += ( diff * diff ); 763 sumDiffs += diff; 764 countInt++; 765 } 766 } 767 countInt = myVector->n; 768 } 746 if ( maskVector != NULL ) { 747 for ( i = 0;i < myVector->n;i++ ) { 748 if ( !( maskVal & maskVector->data.U8[ i ] ) && 749 ( rangeMin <= myVector->data.F32[ i ] ) && 750 ( myVector->data.F32[ i ] <= rangeMax ) ) { 751 diff = myVector->data.F32[ i ] - mean; 752 sumSquares += ( diff * diff ); 753 sumDiffs += diff; 754 countInt++; 755 } 756 } 769 757 } else { 770 if ( maskVector != NULL ) { 771 for ( i = 0;i < myVector->n;i++ ) { 772 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 773 diff = myVector->data.F32[ i ] - mean; 774 sumSquares += ( diff * diff ); 775 sumDiffs += diff; 776 countInt++; 777 } 778 } 779 } else { 780 for ( i = 0;i < myVector->n;i++ ) { 781 diff = myVector->data.F32[ i ] - mean; 782 sumSquares += ( diff * diff ); 783 sumDiffs += diff; 784 countInt++; 785 } 786 countInt = myVector->n; 787 } 788 } 758 for ( i = 0;i < myVector->n;i++ ) { 759 if ( ( rangeMin <= myVector->data.F32[ i ] ) && 760 ( myVector->data.F32[ i ] <= rangeMax ) ) { 761 diff = myVector->data.F32[ i ] - mean; 762 sumSquares += ( diff * diff ); 763 sumDiffs += diff; 764 countInt++; 765 } 766 } 767 countInt = myVector->n; 768 } 769 } else { 770 if ( maskVector != NULL ) { 771 for ( i = 0;i < myVector->n;i++ ) { 772 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 773 diff = myVector->data.F32[ i ] - mean; 774 sumSquares += ( diff * diff ); 775 sumDiffs += diff; 776 countInt++; 777 } 778 } 779 } else { 780 for ( i = 0;i < myVector->n;i++ ) { 781 diff = myVector->data.F32[ i ] - mean; 782 sumSquares += ( diff * diff ); 783 sumDiffs += diff; 784 countInt++; 785 } 786 countInt = myVector->n; 787 } 788 } 789 789 countFloat = ( float ) countInt; 790 790 791 791 #ifdef DARWIN 792 792 793 793 stats->sampleStdev = ( float ) sqrt( ( sumSquares - ( sumDiffs * 794 794 sumDiffs / countFloat ) ) / ( countFloat - 1 ) ); 795 795 #else 796 796 797 797 stats->sampleStdev = sqrtf( ( sumSquares - ( sumDiffs * 798 798 sumDiffs / countFloat ) ) / ( countFloat - 1 ) ); … … 824 824 float oldStanStdev = 0.0; // Temporary variable 825 825 psVector *tmpMask = NULL; // Temporary vector 826 826 827 827 // Endure that stats->clipIter is within the proper range. 828 828 if ( !( ( CLIPPED_NUM_ITER_LB <= stats->clipIter ) && 829 829 ( stats->clipIter <= CLIPPED_NUM_ITER_UB ) ) ) { 830 psAbort( __func__, "Unallowed value for clipIter (%d).\n",831 stats->clipIter );832 }833 830 psAbort( __func__, "Unallowed value for clipIter (%d).\n", 831 stats->clipIter ); 832 } 833 834 834 // Endure that stats->clipSigma is within the proper range. 835 835 if ( !( ( CLIPPED_SIGMA_LB <= stats->clipSigma ) && 836 836 ( stats->clipSigma <= CLIPPED_SIGMA_UB ) ) ) { 837 psAbort( __func__, "Unallowed value for clipSigma (%f).\n",838 stats->clipSigma );839 }840 837 psAbort( __func__, "Unallowed value for clipSigma (%f).\n", 838 stats->clipSigma ); 839 } 840 841 841 // We allocate a temporary mask vector since during the iterative 842 842 // steps that follow, we will be masking off additional data points. … … 844 844 tmpMask = psVectorAlloc( myVector->n, PS_TYPE_U8 ); 845 845 tmpMask->n = myVector->n; 846 846 847 847 // If we were called with a mask vector, then initialize the temporary 848 848 // mask vector with those values. 849 849 if ( maskVector != NULL ) { 850 for ( i = 0;i < tmpMask->n;i++ ) {851 tmpMask->data.U8[ i ] = maskVector->data.U8[ i ];852 }853 }854 850 for ( i = 0;i < tmpMask->n;i++ ) { 851 tmpMask->data.U8[ i ] = maskVector->data.U8[ i ]; 852 } 853 } 854 855 855 // 1. Compute the sample median. 856 856 // NOTE: This seems odd. Verify with IfA that we want to calculate the 857 857 // median here, not the mean. 858 858 p_psVectorSampleMedian( myVector, maskVector, maskVal, stats ); 859 859 860 860 // 2. Compute the sample standard deviation. 861 861 p_psVectorSampleStdev( myVector, maskVector, maskVal, stats ); 862 862 863 863 // 3. Use the sample median as the first estimator of the mean X. 864 864 clippedMean = stats->sampleMean; 865 865 866 866 // 4. Use the sample stdev as the first estimator of the mean stdev. 867 867 clippedStdev = stats->sampleStdev; 868 868 869 869 // Must save the old sampleMean and sampleStdev since the following code 870 870 // block overwrites them. 871 871 oldStanMean = stats->sampleMean; 872 872 oldStanStdev = stats->sampleStdev; 873 873 874 874 // 5. Repeat N times: 875 875 for ( i = 0;i < stats->clipIter;i++ ) { 876 for ( j = 0;j < myVector->n;j++ ) {877 // a) Exclude all values x_i for which |x_i - x| > K * stdev878 if ( fabs( myVector->data.F32[ j ] - clippedMean ) >879 ( stats->clipSigma * clippedStdev ) ) {880 tmpMask->data.U8[ i ] = 0xff;881 }882 // b) compute new mean and stdev883 p_psVectorSampleMedian( myVector, tmpMask, maskVal, stats );884 p_psVectorSampleStdev( myVector, tmpMask, maskVal, stats );885 886 // c) Use the new mean for x887 clippedMean = stats->sampleMean;888 889 // d) Use the new stdev for stdev890 clippedStdev = stats->sampleStdev;891 }892 893 }876 for ( j = 0;j < myVector->n;j++ ) { 877 // a) Exclude all values x_i for which |x_i - x| > K * stdev 878 if ( fabs( myVector->data.F32[ j ] - clippedMean ) > 879 ( stats->clipSigma * clippedStdev ) ) { 880 tmpMask->data.U8[ i ] = 0xff; 881 } 882 // b) compute new mean and stdev 883 p_psVectorSampleMedian( myVector, tmpMask, maskVal, stats ); 884 p_psVectorSampleStdev( myVector, tmpMask, maskVal, stats ); 885 886 // c) Use the new mean for x 887 clippedMean = stats->sampleMean; 888 889 // d) Use the new stdev for stdev 890 clippedStdev = stats->sampleStdev; 891 } 892 893 } 894 894 stats->sampleMean = oldStanMean; 895 895 stats->sampleStdev = oldStanStdev; 896 896 897 897 // 7. The last calcuated value of x is the cliped mean. 898 898 if ( stats->options & PS_STAT_CLIPPED_MEAN ) { 899 stats->clippedMean = clippedMean;900 }901 899 stats->clippedMean = clippedMean; 900 } 901 902 902 // 8. The last calcuated value of stdev is the cliped stdev. 903 903 if ( stats->options & PS_STAT_CLIPPED_STDEV ) { 904 stats->clippedStdev = clippedStdev;905 }906 904 stats->clippedStdev = clippedStdev; 905 } 906 907 907 psFree( tmpMask ); 908 908 } … … 918 918 float range = 0.0; 919 919 int i = 0; 920 920 921 921 for ( i = 0;i < myData->n;i++ ) { 922 if ( myData->data.F32[ i ] < min ) {923 min = myData->data.F32[ i ];924 }925 if ( myData->data.F32[ i ] > max ) {926 max = myData->data.F32[ i ];927 }928 }929 922 if ( myData->data.F32[ i ] < min ) { 923 min = myData->data.F32[ i ]; 924 } 925 if ( myData->data.F32[ i ] > max ) { 926 max = myData->data.F32[ i ]; 927 } 928 } 929 930 930 range = max - min; 931 931 for ( i = 0;i < myData->n;i++ ) { 932 myData->data.F32[ i ] = ( myData->data.F32[ i ] - min ) / range;933 }932 myData->data.F32[ i ] = ( myData->data.F32[ i ] - min ) / range; 933 } 934 934 } 935 935 … … 948 948 float tmp = exp( -( ( x - mean ) * ( x - mean ) ) / ( 2.0 * stdev * stdev ) ); 949 949 tmp /= ( ( float ) sqrt( 2.0 * M_PI * ( stdev * stdev ) ) ); 950 950 951 951 // printf("p_psGaussian((%.2f), %.2f, %.2f) is %.2f\n", x, mean, stdev, tmp); 952 952 return ( tmp ); … … 965 965 float stdev = myParams->data.F32[ 1 ]; 966 966 float tmp = 0.0; 967 967 968 968 if ( whichParam == 0 ) { 969 // Return the derivative w.r.t. the mean. 970 tmp = ( x - mean ) * p_psGaussian( myData, myParams ); 971 tmp /= ( stdev * stdev ); 972 } else if ( whichParam == 1 ) { 969 // Return the derivative w.r.t. the mean. 970 tmp = ( x - mean ) * p_psGaussian( myData, myParams ); 971 tmp /= ( stdev * stdev ); 972 } else 973 if ( whichParam == 1 ) { 973 974 // Return the derivative w.r.t. the stdev. 974 975 tmp = ( x - mean ) * ( x - mean ) * p_psGaussian( myData, myParams ); … … 976 977 } 977 978 printf( "p_psGaussianDeriv((%.2f), %.2f, %.2f, (%d)) is %.2f\n", x, mean, stdev, whichParam, tmp ); 978 979 979 980 return ( tmp ); 980 981 } … … 994 995 float C = myParams->data.F32[ 2 ]; 995 996 float tmp = 0.0; 996 997 997 998 tmp = ( A * x * x ) + ( B * x ) + C; 998 999 return ( tmp ); … … 1009 1010 float x = myCoords->data.F32[ 0 ]; 1010 1011 float tmp = 0.0; 1011 1012 1012 1013 if ( whichParamDeriv == 0 ) { 1013 tmp = x * x; 1014 } else if ( whichParamDeriv == 1 ) { 1014 tmp = x * x; 1015 } else 1016 if ( whichParamDeriv == 1 ) { 1015 1017 tmp = x; 1016 } else if ( whichParamDeriv == 2 ) { 1017 tmp = 1.0; 1018 } 1019 1018 } else 1019 if ( whichParamDeriv == 2 ) { 1020 tmp = 1.0; 1021 } 1022 1020 1023 return ( tmp ); 1021 1024 } … … 1039 1042 float oldMidpoint = 1.0; 1040 1043 float f = 0.0; 1041 1044 1042 1045 // printf("p_ps1DPolyMedian(%f, %f, %f) \n", rangeLow, rangeHigh, getThisValue); 1043 1046 1044 1047 while ( numIterations < MAX_ITERATIONS ) { 1045 midpoint = ( rangeHigh + rangeLow ) / 2.0;1046 if ( fabs( midpoint - oldMidpoint ) <= FLT_EPSILON ) {1047 return ( midpoint );1048 }1049 oldMidpoint = midpoint;1050 1051 f = psPolynomial1DEval( midpoint, myPoly );1052 // printf("p_ps1DPolyMedian() iteration %d. f(%f) is %f\n", numIterations, midpoint, f);1053 if ( fabs( f - getThisValue ) <= FLT_EPSILON ) {1054 return ( midpoint );1055 }1056 1057 if ( f > getThisValue ) {1058 rangeHigh = midpoint;1059 } else {1060 rangeLow = midpoint;1061 }1062 numIterations++;1063 }1048 midpoint = ( rangeHigh + rangeLow ) / 2.0; 1049 if ( fabs( midpoint - oldMidpoint ) <= FLT_EPSILON ) { 1050 return ( midpoint ); 1051 } 1052 oldMidpoint = midpoint; 1053 1054 f = psPolynomial1DEval( midpoint, myPoly ); 1055 // printf("p_ps1DPolyMedian() iteration %d. f(%f) is %f\n", numIterations, midpoint, f); 1056 if ( fabs( f - getThisValue ) <= FLT_EPSILON ) { 1057 return ( midpoint ); 1058 } 1059 1060 if ( f > getThisValue ) { 1061 rangeHigh = midpoint; 1062 } else { 1063 rangeLow = midpoint; 1064 } 1065 numIterations++; 1066 } 1064 1067 return ( midpoint ); 1065 1068 } … … 1082 1085 psVector *yErr = psVectorAlloc( 3, PS_TYPE_F64 ); 1083 1086 psPolynomial1D *myPoly = psPolynomial1DAlloc( 2 ); 1084 1087 1085 1088 if ( ( binNum > 0 ) && 1086 1089 ( binNum < ( histogram->nums->n + 1 ) ) ) { 1087 x->data.F64[ 0 ] = ( double ) 0.5 *1088 ( histogram->bounds->data.F32[ binNum - 1 ] +1089 histogram->bounds->data.F32[ binNum ] );1090 x->data.F64[ 1 ] = ( double ) 0.5 *1091 ( histogram->bounds->data.F32[ binNum ] +1092 histogram->bounds->data.F32[ binNum + 1 ] );1093 x->data.F64[ 2 ] = ( double ) 0.5 *1094 ( histogram->bounds->data.F32[ binNum + 1 ] +1095 histogram->bounds->data.F32[ binNum + 2 ] );1096 1097 y->data.F64[ 0 ] = cumulativeSums->data.F32[ binNum - 1 ];1098 y->data.F64[ 1 ] = cumulativeSums->data.F32[ binNum ];1099 y->data.F64[ 2 ] = cumulativeSums->data.F32[ binNum + 1 ];1100 1101 if ( !( ( y->data.F64[ 0 ] <= fitFloat ) &&1102 ( fitFloat <= y->data.F64[ 2 ] ) ) ) {1103 psAbort( __func__, "p_psVectorRobustStats(0): midpoint not within y-range\n" );1104 }1105 1106 yErr->data.F64[ 0 ] = 1.0;1107 yErr->data.F64[ 1 ] = 1.0;1108 yErr->data.F64[ 2 ] = 1.0;1109 1110 myPoly = psVectorFitPolynomial1D( myPoly, x, y, yErr );1111 return ( p_ps1DPolyMedian( myPoly, x->data.F64[ 0 ], x->data.F64[ 2 ],1112 fitFloat ) );1113 } else {1114 return ( 0.5 * ( histogram->bounds->data.F32[ binNum + 1 ] +1115 histogram->bounds->data.F32[ binNum ] ) );1116 }1117 1090 x->data.F64[ 0 ] = ( double ) 0.5 * 1091 ( histogram->bounds->data.F32[ binNum - 1 ] + 1092 histogram->bounds->data.F32[ binNum ] ); 1093 x->data.F64[ 1 ] = ( double ) 0.5 * 1094 ( histogram->bounds->data.F32[ binNum ] + 1095 histogram->bounds->data.F32[ binNum + 1 ] ); 1096 x->data.F64[ 2 ] = ( double ) 0.5 * 1097 ( histogram->bounds->data.F32[ binNum + 1 ] + 1098 histogram->bounds->data.F32[ binNum + 2 ] ); 1099 1100 y->data.F64[ 0 ] = cumulativeSums->data.F32[ binNum - 1 ]; 1101 y->data.F64[ 1 ] = cumulativeSums->data.F32[ binNum ]; 1102 y->data.F64[ 2 ] = cumulativeSums->data.F32[ binNum + 1 ]; 1103 1104 if ( !( ( y->data.F64[ 0 ] <= fitFloat ) && 1105 ( fitFloat <= y->data.F64[ 2 ] ) ) ) { 1106 psAbort( __func__, "p_psVectorRobustStats(0): midpoint not within y-range\n" ); 1107 } 1108 1109 yErr->data.F64[ 0 ] = 1.0; 1110 yErr->data.F64[ 1 ] = 1.0; 1111 yErr->data.F64[ 2 ] = 1.0; 1112 1113 myPoly = psVectorFitPolynomial1D( myPoly, x, y, yErr ); 1114 return ( p_ps1DPolyMedian( myPoly, x->data.F64[ 0 ], x->data.F64[ 2 ], 1115 fitFloat ) ); 1116 } else { 1117 return ( 0.5 * ( histogram->bounds->data.F32[ binNum + 1 ] + 1118 histogram->bounds->data.F32[ binNum ] ) ); 1119 } 1120 1118 1121 psFree( x ); 1119 1122 psFree( y ); … … 1187 1190 float sumNfit = 0.0; 1188 1191 float cumulativeMedian = 0.0; 1189 1192 1190 1193 // Compute the initial bin size of the robust histogram. This is done 1191 1194 // by computing the clipped standard deviation of the vector, and dividing … … 1193 1196 p_psVectorClippedStats( myVector, maskVector, maskVal, tmpStats ); 1194 1197 binSize = tmpStats->clippedStdev / 10.0f; 1195 1198 1196 1199 // If stats->clippedStdev == 0.0, then all data elements have the same 1197 1200 // value. Therefore, we can set the appropiate results and return. 1198 1201 if ( fabs( binSize ) <= FLT_EPSILON ) { 1199 if ( stats->options & PS_STAT_ROBUST_MEAN ) {1200 stats->robustMean = stats->clippedMean;1201 }1202 if ( stats->options & PS_STAT_ROBUST_MEDIAN ) {1203 stats->robustMedian = stats->clippedMean;1204 }1205 if ( stats->options & PS_STAT_ROBUST_MODE ) {1206 stats->robustMode = stats->clippedMean;1207 }1208 if ( stats->options & PS_STAT_ROBUST_STDEV ) {1209 stats->robustStdev = 0.0;1210 }1211 if ( stats->options & PS_STAT_ROBUST_QUARTILE ) {1212 stats->robustUQ = stats->clippedMean;1213 stats->robustLQ = stats->clippedMean;1214 }1215 // XXX: Set these to the number of unmasked data points?1216 stats->robustNfit = 0.0;1217 stats->robustN50 = 0.0;1218 psFree( tmpStats );1219 return ;1220 }1221 1202 if ( stats->options & PS_STAT_ROBUST_MEAN ) { 1203 stats->robustMean = stats->clippedMean; 1204 } 1205 if ( stats->options & PS_STAT_ROBUST_MEDIAN ) { 1206 stats->robustMedian = stats->clippedMean; 1207 } 1208 if ( stats->options & PS_STAT_ROBUST_MODE ) { 1209 stats->robustMode = stats->clippedMean; 1210 } 1211 if ( stats->options & PS_STAT_ROBUST_STDEV ) { 1212 stats->robustStdev = 0.0; 1213 } 1214 if ( stats->options & PS_STAT_ROBUST_QUARTILE ) { 1215 stats->robustUQ = stats->clippedMean; 1216 stats->robustLQ = stats->clippedMean; 1217 } 1218 // XXX: Set these to the number of unmasked data points? 1219 stats->robustNfit = 0.0; 1220 stats->robustN50 = 0.0; 1221 psFree( tmpStats ); 1222 return ; 1223 } 1224 1222 1225 // Determine minimum and maximum values in the data vector. 1223 1226 if ( isnan( stats->min ) ) { 1224 p_psVectorMin( myVector, maskVector, maskVal, stats );1225 }1227 p_psVectorMin( myVector, maskVector, maskVal, stats ); 1228 } 1226 1229 if ( isnan( stats->max ) ) { 1227 p_psVectorMax( myVector, maskVector, maskVal, stats );1228 }1229 1230 p_psVectorMax( myVector, maskVector, maskVal, stats ); 1231 } 1232 1230 1233 // Create the histogram structure. NOTE: we can not specify the bin size 1231 1234 // precisely since the argument to psHistogramAlloc() is the number of … … 1236 1239 stats->max, 1237 1240 numBins ); 1238 1241 1239 1242 // Populate the histogram array. 1240 1243 psVectorHistogram( robustHistogram, myVector, maskVector, maskVal ); 1241 1244 1242 1245 // Smooth the histogram. 1243 1246 // XXX: is that the right stdev? 1244 1247 robustHistogramVector = p_psVectorsmoothHistGaussian( robustHistogram, 1245 1248 tmpStats->clippedStdev / 4.0f ); 1246 1249 1247 1250 // The following was necessary to fit a gaussian to the data, since 1248 1251 // gaussian functions produce data between 0.0 and 1.0. 1249 1252 // p_psNormalizeVector(robustHistogramVector); 1250 1253 1251 1254 /************************************************************************** 1252 1255 Determine the lower/upper quartiles. 1253 **************************************************************************/ 1256 **************************************************************************/ 1254 1257 // We define a vector called "cumulativeRobustSums..." where the value at 1255 1258 // index position i is equal to the sum of bins 0:i. This will be used … … 1258 1261 cumulativeRobustSumsFullRange->data.F32[ 0 ] = robustHistogramVector->data.F32[ 0 ]; 1259 1262 for ( i = 1;i < robustHistogramVector->n;i++ ) { 1260 cumulativeRobustSumsFullRange->data.F32[ i ] =1261 cumulativeRobustSumsFullRange->data.F32[ i - 1 ] +1262 robustHistogramVector->data.F32[ i ];1263 }1263 cumulativeRobustSumsFullRange->data.F32[ i ] = 1264 cumulativeRobustSumsFullRange->data.F32[ i - 1 ] + 1265 robustHistogramVector->data.F32[ i ]; 1266 } 1264 1267 sumRobust = cumulativeRobustSumsFullRange->data.F32[ robustHistogramVector->n - 1 ]; 1265 1268 1266 1269 // Determine the bin number containing the lower quartile point. 1267 1270 LQBinNum = -1; 1268 1271 for ( i = 0;i < cumulativeRobustSumsFullRange->n;i++ ) { 1269 if ( cumulativeRobustSumsFullRange->data.F32[ i ] >= ( sumRobust / 4.0 ) ) {1270 LQBinNum = i;1271 break;1272 }1273 }1274 1272 if ( cumulativeRobustSumsFullRange->data.F32[ i ] >= ( sumRobust / 4.0 ) ) { 1273 LQBinNum = i; 1274 break; 1275 } 1276 } 1277 1275 1278 // Determine the bin number containing the upper quartile point. 1276 1279 UQBinNum = -1; 1277 1280 for ( i = cumulativeRobustSumsFullRange->n - 1;i >= 0;i-- ) { 1278 if ( cumulativeRobustSumsFullRange->data.F32[ i ] <= ( 3.0 * sumRobust / 4.0 ) ) {1279 UQBinNum = i;1280 break;1281 }1282 }1283 1281 if ( cumulativeRobustSumsFullRange->data.F32[ i ] <= ( 3.0 * sumRobust / 4.0 ) ) { 1282 UQBinNum = i; 1283 break; 1284 } 1285 } 1286 1284 1287 if ( ( LQBinNum == -1 ) || 1285 1288 ( UQBinNum == -1 ) ) { 1286 psAbort( __func__, "Could not determine the robust lower/upper quartiles." );1287 }1289 psAbort( __func__, "Could not determine the robust lower/upper quartiles." ); 1290 } 1288 1291 /************************************************************************** 1289 1292 Determine the mode in the range LQ:UQ. 1290 **************************************************************************/ 1293 **************************************************************************/ 1291 1294 // Determine the bin with the peak value in the range LQ to UQ. 1292 1295 maxBinNum = LQBinNum; … … 1294 1297 sumN50 = ( float ) robustHistogram->nums->data.S32[ LQBinNum ]; 1295 1298 for ( i = LQBinNum + 1;i <= UQBinNum;i++ ) { 1296 if ( robustHistogramVector->data.F32[ i ] > maxBinCount ) {1297 maxBinNum = i;1298 maxBinCount = robustHistogramVector->data.F32[ i ];1299 }1300 sumN50 += ( float ) robustHistogram->nums->data.S32[ i ];1301 }1302 1299 if ( robustHistogramVector->data.F32[ i ] > maxBinCount ) { 1300 maxBinNum = i; 1301 maxBinCount = robustHistogramVector->data.F32[ i ]; 1302 } 1303 sumN50 += ( float ) robustHistogram->nums->data.S32[ i ]; 1304 } 1305 1303 1306 // XXX: is dL defined as the value at the LQ/UQ, or the bin number? 1304 1307 dL = ( UQBinNum - LQBinNum ) / 4; 1305 1308 1306 1309 printf( "(LQBinNum, UQBinNum, maxBinNum) is (%d, %d, %d)\n", LQBinNum, UQBinNum, maxBinNum ); 1307 1310 1308 1311 /************************************************************************** 1309 1312 Determine the mean/stdev for the bins in the range mode-dL to mode+dL … … 1311 1314 cumulativeRobustSumsDlRange = psVectorAlloc( robustHistogramVector->n, PS_TYPE_F32 ); 1312 1315 for ( i = 0;i < robustHistogramVector->n;i++ ) { 1313 cumulativeRobustSumsDlRange->data.F32[ i ] = 0.0;1314 }1316 cumulativeRobustSumsDlRange->data.F32[ i ] = 0.0; 1317 } 1315 1318 sumNfit = 0.0; 1316 1319 cumulativeMedian = 0.0; 1317 1320 for ( i = maxBinNum - dL;i <= maxBinNum + dL;i++ ) { 1318 if ( ( 0 <= i ) && ( i < robustHistogramVector->n ) ) {1319 cumulativeRobustSumsDlRange->data.F32[ i ] =1320 cumulativeRobustSumsDlRange->data.F32[ i - 1 ] +1321 robustHistogramVector->data.F32[ i ];1322 cumulativeMedian += robustHistogramVector->data.F32[ i ];1323 sumNfit += ( float ) robustHistogram->nums->data.S32[ i ];1324 }1325 }1326 1321 if ( ( 0 <= i ) && ( i < robustHistogramVector->n ) ) { 1322 cumulativeRobustSumsDlRange->data.F32[ i ] = 1323 cumulativeRobustSumsDlRange->data.F32[ i - 1 ] + 1324 robustHistogramVector->data.F32[ i ]; 1325 cumulativeMedian += robustHistogramVector->data.F32[ i ]; 1326 sumNfit += ( float ) robustHistogram->nums->data.S32[ i ]; 1327 } 1328 } 1329 1327 1330 // Calculate the mean of the smoothed robust histogram in the range 1328 1331 // mode-dL to mode+dL. We use the midpoint of each bin as the mean for … … 1330 1333 myMean = 0.0; 1331 1334 for ( i = maxBinNum - dL;i <= maxBinNum + dL;i++ ) { 1332 if ( ( 0 <= i ) && ( i < robustHistogramVector->n ) ) {1333 myMean += ( robustHistogramVector->data.F32[ i ] ) * 0.5 *1334 ( robustHistogram->bounds->data.F32[ i + 1 ] +1335 robustHistogram->bounds->data.F32[ i ] );1336 countFloat += robustHistogramVector->data.F32[ i ];1337 }1338 }1335 if ( ( 0 <= i ) && ( i < robustHistogramVector->n ) ) { 1336 myMean += ( robustHistogramVector->data.F32[ i ] ) * 0.5 * 1337 ( robustHistogram->bounds->data.F32[ i + 1 ] + 1338 robustHistogram->bounds->data.F32[ i ] ); 1339 countFloat += robustHistogramVector->data.F32[ i ]; 1340 } 1341 } 1339 1342 myMean /= countFloat; 1340 1343 1341 1344 // Calculate the stdev of the smoothed robust histogram in the range 1342 1345 // mode-dL to mode+dL. We use the midpoint of each bin as the mean for 1343 1346 // that bin. 1344 1347 for ( i = maxBinNum - dL;i <= maxBinNum + dL;i++ ) { 1345 if ( ( 0 <= i ) && ( i < robustHistogramVector->n ) ) {1346 diff = ( 0.5 * ( robustHistogram->bounds->data.F32[ i + 1 ] +1347 robustHistogram->bounds->data.F32[ i ] ) ) - myMean;1348 sumSquares += diff * diff * robustHistogramVector->data.F32[ i ];1349 sumDiffs += diff * robustHistogramVector->data.F32[ i ];1350 }1351 }1348 if ( ( 0 <= i ) && ( i < robustHistogramVector->n ) ) { 1349 diff = ( 0.5 * ( robustHistogram->bounds->data.F32[ i + 1 ] + 1350 robustHistogram->bounds->data.F32[ i ] ) ) - myMean; 1351 sumSquares += diff * diff * robustHistogramVector->data.F32[ i ]; 1352 sumDiffs += diff * robustHistogramVector->data.F32[ i ]; 1353 } 1354 } 1352 1355 myStdev = sqrt( ( sumSquares - ( sumDiffs * sumDiffs / countFloat ) ) / ( countFloat - 1 ) ); 1353 1356 1354 1357 /************************************************************************** 1355 1358 Set the appropriate members in the output stats struct. 1356 1359 **************************************************************************/ 1357 1360 if ( stats->options & PS_STAT_ROBUST_MEAN ) { 1358 stats->robustMean = myMean;1359 }1360 1361 stats->robustMean = myMean; 1362 } 1363 1361 1364 if ( stats->options & PS_STAT_ROBUST_MODE ) { 1362 stats->robustMode = 0.5 *1363 ( robustHistogram->bounds->data.F32[ maxBinNum ] +1364 robustHistogram->bounds->data.F32[ maxBinNum + 1 ] );1365 }1366 1365 stats->robustMode = 0.5 * 1366 ( robustHistogram->bounds->data.F32[ maxBinNum ] + 1367 robustHistogram->bounds->data.F32[ maxBinNum + 1 ] ); 1368 } 1369 1367 1370 if ( stats->options & PS_STAT_ROBUST_STDEV ) { 1368 stats->robustStdev = myStdev;1369 }1370 1371 stats->robustStdev = myStdev; 1372 } 1373 1371 1374 // To determine the median (and later, the lower/upper quartile), we fit 1372 1375 // a quadratic to the three bins surrounding the bin containing the median. … … 1374 1377 // the cumulative number of data points in all bins up to, and including, 1375 1378 // this bin. We then solve the quadratic for 1376 1379 1377 1380 if ( stats->options & PS_STAT_ROBUST_MEDIAN ) { 1378 if ( ( maxBinNum > 0 ) && ( maxBinNum < ( robustHistogram->nums->n - 1 ) ) ) {1379 x->data.F64[ 0 ] = ( double ) 0.5 *1380 ( robustHistogram->bounds->data.F32[ maxBinNum - 1 ] +1381 robustHistogram->bounds->data.F32[ maxBinNum ] );1382 x->data.F64[ 1 ] = ( double ) 0.5 *1383 ( robustHistogram->bounds->data.F32[ maxBinNum ] +1384 robustHistogram->bounds->data.F32[ maxBinNum + 1 ] );1385 x->data.F64[ 2 ] = ( double ) 0.5 *1386 ( robustHistogram->bounds->data.F32[ maxBinNum + 1 ] +1387 robustHistogram->bounds->data.F32[ maxBinNum + 2 ] );1388 1389 y->data.F64[ 0 ] = cumulativeRobustSumsDlRange->data.F32[ maxBinNum - 1 ];1390 y->data.F64[ 1 ] = cumulativeRobustSumsDlRange->data.F32[ maxBinNum ];1391 y->data.F64[ 2 ] = cumulativeRobustSumsDlRange->data.F32[ maxBinNum + 1 ];1392 1393 // Ensure that cumulativeMedian/2 is actually within the range of the bins1394 // we are using.1395 cumulativeMedian *= 0.5;1396 if ( !( ( y->data.F64[ 0 ] <= cumulativeMedian ) &&1397 ( cumulativeMedian <= y->data.F64[ 2 ] ) ) ) {1398 printf( "((%f), %f, %f)\n", cumulativeMedian, y->data.F64[ 0 ], y->data.F64[ 2 ] );1399 psAbort( __func__, "p_psVectorRobustStats(1): midpoint not within y-range\n" );1400 }1401 // XXX: yErr is not currently used by psVectorFitPolynomial1D(). We1402 // may have to set this meaningfully later.1403 yErr->data.F64[ 0 ] = 1.0;1404 yErr->data.F64[ 1 ] = 1.0;1405 yErr->data.F64[ 2 ] = 1.0;1406 1407 // Determine the coefficients of the polynomial.1408 myPoly = psVectorFitPolynomial1D( myPoly, x, y, yErr );1409 // Call p_ps1DPolyMedian(), which does a binary search on the1410 // polynomial, looking for the value x such that1411 // f(x) = cumulativeMedian.1412 stats->robustMedian = p_ps1DPolyMedian( myPoly, x->data.F64[ 0 ],1413 x->data.F64[ 2 ], cumulativeMedian );1414 } else {1415 // If the mode is the first/last histogram bin, then simply use1416 // the midpoint of that bin.1417 stats->robustMedian = 0.5 * ( robustHistogram->bounds->data.F32[ maxBinNum + 1 ] +1418 robustHistogram->bounds->data.F32[ maxBinNum ] );1419 }1420 }1421 1381 if ( ( maxBinNum > 0 ) && ( maxBinNum < ( robustHistogram->nums->n - 1 ) ) ) { 1382 x->data.F64[ 0 ] = ( double ) 0.5 * 1383 ( robustHistogram->bounds->data.F32[ maxBinNum - 1 ] + 1384 robustHistogram->bounds->data.F32[ maxBinNum ] ); 1385 x->data.F64[ 1 ] = ( double ) 0.5 * 1386 ( robustHistogram->bounds->data.F32[ maxBinNum ] + 1387 robustHistogram->bounds->data.F32[ maxBinNum + 1 ] ); 1388 x->data.F64[ 2 ] = ( double ) 0.5 * 1389 ( robustHistogram->bounds->data.F32[ maxBinNum + 1 ] + 1390 robustHistogram->bounds->data.F32[ maxBinNum + 2 ] ); 1391 1392 y->data.F64[ 0 ] = cumulativeRobustSumsDlRange->data.F32[ maxBinNum - 1 ]; 1393 y->data.F64[ 1 ] = cumulativeRobustSumsDlRange->data.F32[ maxBinNum ]; 1394 y->data.F64[ 2 ] = cumulativeRobustSumsDlRange->data.F32[ maxBinNum + 1 ]; 1395 1396 // Ensure that cumulativeMedian/2 is actually within the range of the bins 1397 // we are using. 1398 cumulativeMedian *= 0.5; 1399 if ( !( ( y->data.F64[ 0 ] <= cumulativeMedian ) && 1400 ( cumulativeMedian <= y->data.F64[ 2 ] ) ) ) { 1401 printf( "((%f), %f, %f)\n", cumulativeMedian, y->data.F64[ 0 ], y->data.F64[ 2 ] ); 1402 psAbort( __func__, "p_psVectorRobustStats(1): midpoint not within y-range\n" ); 1403 } 1404 // XXX: yErr is not currently used by psVectorFitPolynomial1D(). We 1405 // may have to set this meaningfully later. 1406 yErr->data.F64[ 0 ] = 1.0; 1407 yErr->data.F64[ 1 ] = 1.0; 1408 yErr->data.F64[ 2 ] = 1.0; 1409 1410 // Determine the coefficients of the polynomial. 1411 myPoly = psVectorFitPolynomial1D( myPoly, x, y, yErr ); 1412 // Call p_ps1DPolyMedian(), which does a binary search on the 1413 // polynomial, looking for the value x such that 1414 // f(x) = cumulativeMedian. 1415 stats->robustMedian = p_ps1DPolyMedian( myPoly, x->data.F64[ 0 ], 1416 x->data.F64[ 2 ], cumulativeMedian ); 1417 } else { 1418 // If the mode is the first/last histogram bin, then simply use 1419 // the midpoint of that bin. 1420 stats->robustMedian = 0.5 * ( robustHistogram->bounds->data.F32[ maxBinNum + 1 ] + 1421 robustHistogram->bounds->data.F32[ maxBinNum ] ); 1422 } 1423 } 1424 1422 1425 // The lower/upper quartile calculations are very similar to the median 1423 1426 // calculations. We fit a quadratic to the array containing the … … 1426 1429 // 1427 1430 if ( stats->options & PS_STAT_ROBUST_QUARTILE ) { 1428 countFloat = cumulativeRobustSumsFullRange->data.F32[ robustHistogramVector->n - 1 ];1429 1430 if ( ( LQBinNum > 0 ) && ( LQBinNum < ( robustHistogram->nums->n - 1 ) ) ) {1431 x->data.F64[ 0 ] = ( double ) 0.5 *1432 ( robustHistogram->bounds->data.F32[ LQBinNum - 1 ] +1433 robustHistogram->bounds->data.F32[ LQBinNum ] );1434 x->data.F64[ 1 ] = ( double ) 0.5 *1435 ( robustHistogram->bounds->data.F32[ LQBinNum ] +1436 robustHistogram->bounds->data.F32[ LQBinNum + 1 ] );1437 x->data.F64[ 2 ] = ( double ) 0.5 *1438 ( robustHistogram->bounds->data.F32[ LQBinNum + 1 ] +1439 robustHistogram->bounds->data.F32[ LQBinNum + 2 ] );1440 1441 y->data.F64[ 0 ] = cumulativeRobustSumsFullRange->data.F32[ LQBinNum - 1 ];1442 y->data.F64[ 1 ] = cumulativeRobustSumsFullRange->data.F32[ LQBinNum ];1443 y->data.F64[ 2 ] = cumulativeRobustSumsFullRange->data.F32[ LQBinNum + 1 ];1444 1445 if ( !( ( y->data.F64[ 0 ] <= ( countFloat / 4.0 ) ) &&1446 ( ( countFloat / 4.0 ) <= y->data.F64[ 2 ] ) ) ) {1447 psAbort( __func__, "p_psVectorRobustStats(2): midpoint not within y-range\n" );1448 }1449 1450 yErr->data.F64[ 0 ] = 1.0;1451 yErr->data.F64[ 1 ] = 1.0;1452 yErr->data.F64[ 2 ] = 1.0;1453 1454 myPoly = psVectorFitPolynomial1D( myPoly, x, y, yErr );1455 stats->robustLQ = p_ps1DPolyMedian( myPoly,1456 x->data.F64[ 0 ],1457 x->data.F64[ 2 ],1458 countFloat / 4.0 );1459 1460 } else {1461 // If the LQ is the first/last histogram bin, then simply use1462 // the midpoint of that bin.1463 stats->robustLQ = 0.5 * ( robustHistogram->bounds->data.F32[ LQBinNum + 1 ] +1464 robustHistogram->bounds->data.F32[ LQBinNum ] );1465 }1466 1467 if ( ( UQBinNum > 0 ) && ( UQBinNum < ( robustHistogram->nums->n - 1 ) ) ) {1468 x->data.F64[ 0 ] = ( double ) 0.5 *1469 ( robustHistogram->bounds->data.F32[ UQBinNum - 1 ] +1470 robustHistogram->bounds->data.F32[ UQBinNum ] );1471 x->data.F64[ 1 ] = ( double ) 0.5 *1472 ( robustHistogram->bounds->data.F32[ UQBinNum ] +1473 robustHistogram->bounds->data.F32[ UQBinNum + 1 ] );1474 x->data.F64[ 2 ] = ( double ) 0.5 *1475 ( robustHistogram->bounds->data.F32[ UQBinNum + 1 ] +1476 robustHistogram->bounds->data.F32[ UQBinNum + 2 ] );1477 1478 y->data.F64[ 0 ] = cumulativeRobustSumsFullRange->data.F32[ UQBinNum - 1 ];1479 y->data.F64[ 1 ] = cumulativeRobustSumsFullRange->data.F32[ UQBinNum ];1480 y->data.F64[ 2 ] = cumulativeRobustSumsFullRange->data.F32[ UQBinNum + 1 ];1481 1482 if ( !( ( y->data.F64[ 0 ] <= ( 3.0 * countFloat / 4.0 ) ) &&1483 ( ( 3.0 * countFloat / 4.0 ) <= y->data.F64[ 2 ] ) ) ) {1484 psAbort( __func__, "p_psVectorRobustStats(3): midpoint not within y-range\n" );1485 }1486 1487 yErr->data.F64[ 0 ] = 1.0;1488 yErr->data.F64[ 1 ] = 1.0;1489 yErr->data.F64[ 2 ] = 1.0;1490 1491 myPoly = psVectorFitPolynomial1D( myPoly, x, y, yErr );1492 stats->robustUQ = p_ps1DPolyMedian( myPoly,1493 x->data.F64[ 0 ],1494 x->data.F64[ 2 ],1495 3.0 * countFloat / 4.0 );1496 } else {1497 // If the UQ is the first/last histogram bin, then simply use1498 // the midpoint of that bin.1499 stats->robustUQ = 0.5 * ( robustHistogram->bounds->data.F32[ UQBinNum + 1 ] +1500 robustHistogram->bounds->data.F32[ UQBinNum ] );1501 }1502 }1431 countFloat = cumulativeRobustSumsFullRange->data.F32[ robustHistogramVector->n - 1 ]; 1432 1433 if ( ( LQBinNum > 0 ) && ( LQBinNum < ( robustHistogram->nums->n - 1 ) ) ) { 1434 x->data.F64[ 0 ] = ( double ) 0.5 * 1435 ( robustHistogram->bounds->data.F32[ LQBinNum - 1 ] + 1436 robustHistogram->bounds->data.F32[ LQBinNum ] ); 1437 x->data.F64[ 1 ] = ( double ) 0.5 * 1438 ( robustHistogram->bounds->data.F32[ LQBinNum ] + 1439 robustHistogram->bounds->data.F32[ LQBinNum + 1 ] ); 1440 x->data.F64[ 2 ] = ( double ) 0.5 * 1441 ( robustHistogram->bounds->data.F32[ LQBinNum + 1 ] + 1442 robustHistogram->bounds->data.F32[ LQBinNum + 2 ] ); 1443 1444 y->data.F64[ 0 ] = cumulativeRobustSumsFullRange->data.F32[ LQBinNum - 1 ]; 1445 y->data.F64[ 1 ] = cumulativeRobustSumsFullRange->data.F32[ LQBinNum ]; 1446 y->data.F64[ 2 ] = cumulativeRobustSumsFullRange->data.F32[ LQBinNum + 1 ]; 1447 1448 if ( !( ( y->data.F64[ 0 ] <= ( countFloat / 4.0 ) ) && 1449 ( ( countFloat / 4.0 ) <= y->data.F64[ 2 ] ) ) ) { 1450 psAbort( __func__, "p_psVectorRobustStats(2): midpoint not within y-range\n" ); 1451 } 1452 1453 yErr->data.F64[ 0 ] = 1.0; 1454 yErr->data.F64[ 1 ] = 1.0; 1455 yErr->data.F64[ 2 ] = 1.0; 1456 1457 myPoly = psVectorFitPolynomial1D( myPoly, x, y, yErr ); 1458 stats->robustLQ = p_ps1DPolyMedian( myPoly, 1459 x->data.F64[ 0 ], 1460 x->data.F64[ 2 ], 1461 countFloat / 4.0 ); 1462 1463 } else { 1464 // If the LQ is the first/last histogram bin, then simply use 1465 // the midpoint of that bin. 1466 stats->robustLQ = 0.5 * ( robustHistogram->bounds->data.F32[ LQBinNum + 1 ] + 1467 robustHistogram->bounds->data.F32[ LQBinNum ] ); 1468 } 1469 1470 if ( ( UQBinNum > 0 ) && ( UQBinNum < ( robustHistogram->nums->n - 1 ) ) ) { 1471 x->data.F64[ 0 ] = ( double ) 0.5 * 1472 ( robustHistogram->bounds->data.F32[ UQBinNum - 1 ] + 1473 robustHistogram->bounds->data.F32[ UQBinNum ] ); 1474 x->data.F64[ 1 ] = ( double ) 0.5 * 1475 ( robustHistogram->bounds->data.F32[ UQBinNum ] + 1476 robustHistogram->bounds->data.F32[ UQBinNum + 1 ] ); 1477 x->data.F64[ 2 ] = ( double ) 0.5 * 1478 ( robustHistogram->bounds->data.F32[ UQBinNum + 1 ] + 1479 robustHistogram->bounds->data.F32[ UQBinNum + 2 ] ); 1480 1481 y->data.F64[ 0 ] = cumulativeRobustSumsFullRange->data.F32[ UQBinNum - 1 ]; 1482 y->data.F64[ 1 ] = cumulativeRobustSumsFullRange->data.F32[ UQBinNum ]; 1483 y->data.F64[ 2 ] = cumulativeRobustSumsFullRange->data.F32[ UQBinNum + 1 ]; 1484 1485 if ( !( ( y->data.F64[ 0 ] <= ( 3.0 * countFloat / 4.0 ) ) && 1486 ( ( 3.0 * countFloat / 4.0 ) <= y->data.F64[ 2 ] ) ) ) { 1487 psAbort( __func__, "p_psVectorRobustStats(3): midpoint not within y-range\n" ); 1488 } 1489 1490 yErr->data.F64[ 0 ] = 1.0; 1491 yErr->data.F64[ 1 ] = 1.0; 1492 yErr->data.F64[ 2 ] = 1.0; 1493 1494 myPoly = psVectorFitPolynomial1D( myPoly, x, y, yErr ); 1495 stats->robustUQ = p_ps1DPolyMedian( myPoly, 1496 x->data.F64[ 0 ], 1497 x->data.F64[ 2 ], 1498 3.0 * countFloat / 4.0 ); 1499 } else { 1500 // If the UQ is the first/last histogram bin, then simply use 1501 // the midpoint of that bin. 1502 stats->robustUQ = 0.5 * ( robustHistogram->bounds->data.F32[ UQBinNum + 1 ] + 1503 robustHistogram->bounds->data.F32[ UQBinNum ] ); 1504 } 1505 } 1503 1506 stats->robustNfit = sumNfit; 1504 1507 stats->robustN50 = sumN50; 1505 1508 1506 1509 psFree( x ); 1507 1510 psFree( y ); … … 1576 1579 { 1577 1580 psStats * newStruct = NULL; 1578 1581 1579 1582 newStruct = ( psStats * ) psAlloc( sizeof( psStats ) ); 1580 1583 newStruct->sampleMean = NAN; … … 1600 1603 newStruct->binsize = NAN; 1601 1604 newStruct->options = options; 1602 1605 1603 1606 return ( newStruct ); 1604 1607 } … … 1623 1626 psHistogram *newHist = NULL; // The new histogram structure 1624 1627 float binSize = 0.0; // The histogram bin size 1625 1628 1626 1629 // NOTE: Verify that this is the correct action. 1627 1630 if ( n == 0 ) { 1628 return ( NULL );1629 }1631 return ( NULL ); 1632 } 1630 1633 if ( n < 0 ) { 1631 psAbort( __func__, "psHistogramAlloc() called with bin size %d.\n", n );1632 }1633 1634 psAbort( __func__, "psHistogramAlloc() called with bin size %d.\n", n ); 1635 } 1636 1634 1637 // NOTE: Verify that this is the correct action. 1635 1638 if ( lower > upper ) { 1636 return ( NULL );1637 }1638 1639 return ( NULL ); 1640 } 1641 1639 1642 // Allocate memory for the new histogram structure. If there are N 1640 1643 // bins, then there are N+1 bounds to those bins. … … 1643 1646 newHist->bounds = psVectorAlloc( n + 1, PS_TYPE_F32 ); 1644 1647 newHist->bounds->n = newHist->bounds->nalloc; 1645 1648 1646 1649 // Calculate the bounds for each bin. 1647 1650 binSize = ( upper - lower ) / ( float ) n; … … 1650 1653 binSize += FLT_EPSILON; 1651 1654 for ( i = 0;i < n + 1;i++ ) { 1652 newHist->bounds->data.F32[ i ] = lower + ( binSize * ( float ) i );1653 }1654 1655 newHist->bounds->data.F32[ i ] = lower + ( binSize * ( float ) i ); 1656 } 1657 1655 1658 // Allocate the bins, and initialize them to zero. 1656 1659 newHist->nums = psVectorAlloc( n, PS_TYPE_U32 ); 1657 1660 newHist->nums->n = newHist->nums->nalloc; 1658 1661 for ( i = 0;i < newHist->nums->n;i++ ) { 1659 newHist->nums->data.U32[ i ] = 0;1660 }1661 1662 newHist->nums->data.U32[ i ] = 0; 1663 } 1664 1662 1665 // Initialize the other members. 1663 1666 newHist->minNum = 0; 1664 1667 newHist->maxNum = 0; 1665 1668 newHist->uniform = true; 1666 1669 1667 1670 return ( newHist ); 1668 1671 } … … 1681 1684 psHistogram * newHist = NULL; // The new histogram structure 1682 1685 int i; // Loop index variable 1683 1686 1684 1687 // NOTE: Verify that this is the correct action. 1685 1688 if ( bounds == NULL ) { 1686 // psAbort(__func__, "psHistogram requested with NULL bounds");1687 return ( NULL );1688 }1689 1689 // psAbort(__func__, "psHistogram requested with NULL bounds"); 1690 return ( NULL ); 1691 } 1692 1690 1693 // NOTE: Verify that this is the correct action. 1691 1694 if ( bounds->n <= 1 ) { 1692 // psAbort(__func__, "psHistogram requested with NULL bounds");1693 return ( NULL );1694 }1695 1695 // psAbort(__func__, "psHistogram requested with NULL bounds"); 1696 return ( NULL ); 1697 } 1698 1696 1699 if ( bounds->type.type != PS_TYPE_F32 ) { 1697 // psAbort(__func__, "psHistogram request a bound which is not type F32");1698 return ( NULL );1699 }1700 1700 // psAbort(__func__, "psHistogram request a bound which is not type F32"); 1701 return ( NULL ); 1702 } 1703 1701 1704 // Allocate memory for the new histogram structure. 1702 1705 newHist = ( psHistogram * ) psAlloc( sizeof( psHistogram ) ); … … 1705 1708 newHist->bounds->n = newHist->bounds->nalloc; 1706 1709 for ( i = 0;i < bounds->n;i++ ) { 1707 newHist->bounds->data.F32[ i ] = bounds->data.F32[ i ];1708 }1709 1710 newHist->bounds->data.F32[ i ] = bounds->data.F32[ i ]; 1711 } 1712 1710 1713 // Allocate the bins, and initialize them to zero. If there are N bounds, 1711 1714 // then there are N-1 bins. … … 1713 1716 newHist->nums->n = newHist->nums->nalloc; 1714 1717 for ( i = 0;i < newHist->nums->n;i++ ) { 1715 newHist->nums->data.U32[ i ] = 0;1716 }1717 1718 newHist->nums->data.U32[ i ] = 0; 1719 } 1720 1718 1721 // Initialize the other members. 1719 1722 newHist->minNum = 0; 1720 1723 newHist->maxNum = 0; 1721 1724 newHist->uniform = false; 1722 1725 1723 1726 return ( newHist ); 1724 1727 } … … 1755 1758 int binNum = 0; // A temporary bin number 1756 1759 int numBins = 0; // The total number of bins 1757 1760 1758 1761 // NOTE: Verify that this is the correct action. 1759 1762 if ( out == NULL ) { 1760 return ( NULL );1761 }1762 1763 return ( NULL ); 1764 } 1765 1763 1766 // Check the specified output histogram for type psF32 1764 1767 if ( out->bounds->type.type != PS_TYPE_F32 ) { 1765 psAbort( __func__,1766 "Only data type PS_TYPE_F32 for the output.bounds member." );1767 }1768 1768 psAbort( __func__, 1769 "Only data type PS_TYPE_F32 for the output.bounds member." ); 1770 } 1771 1769 1772 if ( out->nums->type.type != PS_TYPE_U32 ) { 1770 psAbort( __func__,1771 "Only data type PS_TYPE_U32 for output.nums member." );1772 }1773 1773 psAbort( __func__, 1774 "Only data type PS_TYPE_U32 for output.nums member." ); 1775 } 1776 1774 1777 // NOTE: Verify that this is the correct action. 1775 1778 if ( in == NULL ) { 1776 return ( out );1777 }1778 1779 return ( out ); 1780 } 1781 1779 1782 if ( in->type.type != PS_TYPE_F32 ) { 1783 psAbort( __func__, 1784 "Only data type PS_TYPE_F32 is currently supported (0x%x).", 1785 in->type.type ); 1786 } 1787 1788 if ( mask != NULL ) { 1789 if ( in->n != mask->n ) { 1780 1790 psAbort( __func__, 1781 "Only data type PS_TYPE_F32 is currently supported (0x%x).", 1782 in->type.type ); 1783 } 1784 1785 if ( mask != NULL ) { 1786 if ( in->n != mask->n ) { 1787 psAbort( __func__, 1788 "Vector data and vector mask are of different sizes." ); 1789 } 1790 if ( mask->type.type != PS_TYPE_U8 ) { 1791 psAbort( __func__, "Vector mask must be type PS_TYPE_U8" ); 1792 } 1793 } 1791 "Vector data and vector mask are of different sizes." ); 1792 } 1793 if ( mask->type.type != PS_TYPE_U8 ) { 1794 psAbort( __func__, "Vector mask must be type PS_TYPE_U8" ); 1795 } 1796 } 1794 1797 // NOTE: determine the correct action for a variety of other cases: 1795 1798 // in vector has 0 elements, and histogram structure has zero bins. 1796 1799 1797 1800 numBins = out->nums->n; 1798 1801 for ( i = 0;i < in->n;i++ ) { 1799 // Check if this pixel is masked, and if so, skip it. 1800 if ( ( mask == NULL ) || 1801 ( ( mask != NULL ) && ( !( mask->data.U8[ i ] & maskVal ) ) ) ) { 1802 // Check if this pixel is below the minimum value, and if so 1803 // count it, then skip it. 1804 if ( in->data.F32[ i ] < out->bounds->data.F32[ 0 ] ) { 1805 out->minNum++; 1806 // Check if this pixel is above the maximum value, and if so 1807 // count it, then skip it. 1808 } else if ( in->data.F32[ i ] > out->bounds->data.F32[ numBins ] ) { 1809 out->maxNum++; 1810 } else { 1811 // If this is a uniform histogram, determining the correct 1812 // number is trivial. 1813 if ( out->uniform == true ) { 1814 binSize = out->bounds->data.F32[ 1 ] - out->bounds->data.F32[ 0 ]; 1815 binNum = ( int ) ( ( in->data.F32[ i ] - out->bounds->data.F32[ 0 ] ) / 1816 binSize ); 1817 1818 // NOTE: This next if-statement really shouldn't be necessary. 1819 // However, do to numerical lack of precision, we occasionally 1820 // produce a binNum outside the range of bins. 1821 if ( binNum >= out->nums->n ) { 1822 binNum = out->nums->n - 1; 1823 } 1824 1825 ( out->nums->data.S32[ binNum ] ) ++; 1826 1827 // If this is a non-uniform histogram, determining the correct 1828 // bin number requires a bit more work. 1829 } else { 1830 // NOTE: This is slow. Put a smarter algorithm here to 1831 // find the correct bin number (bin search, probably) 1832 for ( j = 0;j < ( out->bounds->n ) - 1;j++ ) { 1833 if ( ( out->bounds->data.S32[ j ] <= in->data.F32[ i ] ) && 1834 ( in->data.F32[ i ] <= out->bounds->data.S32[ j + 1 ] ) ) { 1835 ( out->nums->data.S32[ j ] ) ++; 1836 } 1837 } 1838 } 1802 // Check if this pixel is masked, and if so, skip it. 1803 if ( ( mask == NULL ) || 1804 ( ( mask != NULL ) && ( !( mask->data.U8[ i ] & maskVal ) ) ) ) { 1805 // Check if this pixel is below the minimum value, and if so 1806 // count it, then skip it. 1807 if ( in->data.F32[ i ] < out->bounds->data.F32[ 0 ] ) { 1808 out->minNum++; 1809 // Check if this pixel is above the maximum value, and if so 1810 // count it, then skip it. 1811 } else 1812 if ( in->data.F32[ i ] > out->bounds->data.F32[ numBins ] ) { 1813 out->maxNum++; 1814 } else { 1815 // If this is a uniform histogram, determining the correct 1816 // number is trivial. 1817 if ( out->uniform == true ) { 1818 binSize = out->bounds->data.F32[ 1 ] - out->bounds->data.F32[ 0 ]; 1819 binNum = ( int ) ( ( in->data.F32[ i ] - out->bounds->data.F32[ 0 ] ) / 1820 binSize ); 1821 1822 // NOTE: This next if-statement really shouldn't be necessary. 1823 // However, do to numerical lack of precision, we occasionally 1824 // produce a binNum outside the range of bins. 1825 if ( binNum >= out->nums->n ) { 1826 binNum = out->nums->n - 1; 1839 1827 } 1840 } 1841 } 1828 1829 ( out->nums->data.S32[ binNum ] ) ++; 1830 1831 // If this is a non-uniform histogram, determining the correct 1832 // bin number requires a bit more work. 1833 } else { 1834 // NOTE: This is slow. Put a smarter algorithm here to 1835 // find the correct bin number (bin search, probably) 1836 for ( j = 0;j < ( out->bounds->n ) - 1;j++ ) { 1837 if ( ( out->bounds->data.S32[ j ] <= in->data.F32[ i ] ) && 1838 ( in->data.F32[ i ] <= out->bounds->data.S32[ j + 1 ] ) ) { 1839 ( out->nums->data.S32[ j ] ) ++; 1840 } 1841 } 1842 } 1843 } 1844 } 1845 } 1842 1846 return ( out ); 1843 1847 } … … 1859 1863 int i = 0; 1860 1864 psVector *tmp = NULL; 1861 1865 1862 1866 if ( in->type.type == PS_TYPE_S32 ) { 1867 tmp = psVectorAlloc( in->n, PS_TYPE_F32 ); 1868 for ( i = 0;i < in->n;i++ ) { 1869 tmp->data.F32[ i ] = ( float ) in->data.S32[ i ]; 1870 } 1871 } else 1872 if ( in->type.type == PS_TYPE_U32 ) { 1863 1873 tmp = psVectorAlloc( in->n, PS_TYPE_F32 ); 1864 1874 for ( i = 0;i < in->n;i++ ) { 1865 tmp->data.F32[ i ] = ( float ) in->data.S32[ i ]; 1866 } 1867 } else if ( in->type.type == PS_TYPE_U32 ) { 1868 tmp = psVectorAlloc( in->n, PS_TYPE_F32 ); 1869 for ( i = 0;i < in->n;i++ ) { 1870 tmp->data.F32[ i ] = ( float ) in->data.U32[ i ]; 1871 } 1872 } else if ( in->type.type == PS_TYPE_F64 ) { 1873 tmp = psVectorAlloc( in->n, PS_TYPE_F32 ); 1874 for ( i = 0;i < in->n;i++ ) { 1875 tmp->data.F32[ i ] = ( float ) in->data.U32[ i ]; 1876 } 1877 } else 1878 if ( in->type.type == PS_TYPE_F64 ) { 1879 tmp = psVectorAlloc( in->n, PS_TYPE_F32 ); 1880 for ( i = 0;i < in->n;i++ ) { 1875 1881 tmp->data.F32[ i ] = ( float ) in->data.F64[ i ]; 1876 1882 } 1877 } else if ( in->type.type == PS_TYPE_F32 ) { 1878 // do nothing 1879 } else { 1880 psAbort( __func__, "unsupported vector type 0x%x\n", in->type.type ); 1881 } 1883 } else 1884 if ( in->type.type == PS_TYPE_F32 ) { 1885 // do nothing 1886 } else { 1887 psAbort( __func__, "unsupported vector type 0x%x\n", in->type.type ); 1888 } 1882 1889 return ( tmp ); 1883 1890 } … … 1908 1915 psVector * inF32; 1909 1916 int mustFreeTmp = 1; 1910 1917 1911 1918 // NOTE: Verify that this is the correct action. 1912 1919 if ( in == NULL ) { 1913 return ( stats );1914 }1920 return ( stats ); 1921 } 1915 1922 if ( stats == NULL ) { 1916 return ( NULL );1917 }1918 1923 return ( NULL ); 1924 } 1925 1919 1926 inF32 = p_psConvertToF32( stats, in, mask, maskVal ); 1920 1927 if ( inF32 == NULL ) { 1921 inF32 = in;1922 mustFreeTmp = 0;1923 }1924 1928 inF32 = in; 1929 mustFreeTmp = 0; 1930 } 1931 1925 1932 // XXX: Should we abort if (stats->min == stats->max)? 1926 1933 if ( ( stats->options & PS_STAT_USE_RANGE ) && 1927 1934 ( stats->min >= stats->max ) ) { 1928 psAbort( __func__, "psVectorStats() called with range: %f to %f\n",1929 stats->min, stats->max );1930 }1931 1935 psAbort( __func__, "psVectorStats() called with range: %f to %f\n", 1936 stats->min, stats->max ); 1937 } 1938 1932 1939 // PS_CHECK_VECTOR_TYPE(in, PS_TYPE_F32); 1933 1940 if ( mask != NULL ) { 1934 PS_CHECK_NULL_VECTOR( mask );1935 PS_CHECK_EMPTY_VECTOR( mask );1936 PS_CHECK_VECTOR_SIZE_EQUAL( mask, in );1937 PS_CHECK_VECTOR_TYPE( mask, PS_TYPE_U8 );1938 }1939 1941 PS_CHECK_NULL_VECTOR( mask ); 1942 PS_CHECK_EMPTY_VECTOR( mask ); 1943 PS_CHECK_VECTOR_SIZE_EQUAL( mask, in ); 1944 PS_CHECK_VECTOR_TYPE( mask, PS_TYPE_U8 ); 1945 } 1946 1940 1947 // ************************************************************************ 1941 1948 if ( stats->options & PS_STAT_SAMPLE_MEAN ) { 1942 p_psVectorSampleMean( in, mask, maskVal, stats );1943 }1944 1949 p_psVectorSampleMean( in, mask, maskVal, stats ); 1950 } 1951 1945 1952 // ************************************************************************ 1946 1953 if ( stats->options & PS_STAT_SAMPLE_MEDIAN ) { 1947 p_psVectorSampleMedian( in, mask, maskVal, stats );1948 }1949 1954 p_psVectorSampleMedian( in, mask, maskVal, stats ); 1955 } 1956 1950 1957 // ************************************************************************ 1951 1958 // NOTE: The Stdev calculation requires the mean. Should we assume the 1952 1959 // mean has already been calculated? Or should we always calculate it? 1953 1960 if ( stats->options & PS_STAT_SAMPLE_STDEV ) { 1954 p_psVectorSampleMean( in, mask, maskVal, stats );1955 p_psVectorSampleStdev( in, mask, maskVal, stats );1956 }1957 1961 p_psVectorSampleMean( in, mask, maskVal, stats ); 1962 p_psVectorSampleStdev( in, mask, maskVal, stats ); 1963 } 1964 1958 1965 // ************************************************************************ 1959 1966 if ( stats->options & PS_STAT_SAMPLE_QUARTILE ) { 1960 p_psVectorSampleQuartiles( in, mask, maskVal, stats );1961 }1962 1967 p_psVectorSampleQuartiles( in, mask, maskVal, stats ); 1968 } 1969 1963 1970 // Since the various robust stats quantities share much computation, they 1964 1971 // are grouped together in a single private function: … … 1969 1976 ( stats->options & PS_STAT_ROBUST_STDEV ) || 1970 1977 ( stats->options & PS_STAT_ROBUST_QUARTILE ) ) { 1971 p_psVectorRobustStats( in, mask, maskVal, stats );1972 }1973 1978 p_psVectorRobustStats( in, mask, maskVal, stats ); 1979 } 1980 1974 1981 if ( ( stats->options & PS_STAT_CLIPPED_MEAN ) || 1975 1982 ( stats->options & PS_STAT_CLIPPED_STDEV ) ) { 1976 p_psVectorClippedStats( in, mask, maskVal, stats );1977 }1978 1983 p_psVectorClippedStats( in, mask, maskVal, stats ); 1984 } 1985 1979 1986 // ************************************************************************ 1980 1987 if ( stats->options & PS_STAT_MAX ) { 1981 p_psVectorMax( in, mask, maskVal, stats );1982 }1983 1988 p_psVectorMax( in, mask, maskVal, stats ); 1989 } 1990 1984 1991 // ************************************************************************ 1985 1992 if ( stats->options & PS_STAT_MIN ) { 1986 p_psVectorMin( in, mask, maskVal, stats );1987 }1988 1993 p_psVectorMin( in, mask, maskVal, stats ); 1994 } 1995 1989 1996 if ( mustFreeTmp == 1 ) { 1990 psFree( inF32 );1991 }1997 psFree( inF32 ); 1998 } 1992 1999 return ( stats ); 1993 2000 } -
trunk/psLib/src/dataManip/psStats.h
r1322 r1385 9 9 * @author George Gusciora, MHPCC 10 10 * 11 * @version $Revision: 1.1 8$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-0 7-29 01:59:06$11 * @version $Revision: 1.19 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-08-04 23:37:39 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/dataManip/psVectorFFT.c
r1366 r1385 5 5 * @author Robert DeSonia, MHPCC 6 6 * 7 * @version $Revision: 1.1 5$ $Name: not supported by cvs2svn $8 * @date $Date: 2004-08-0 2 19:43:59 $7 * @version $Revision: 1.16 $ $Name: not supported by cvs2svn $ 8 * @date $Date: 2004-08-04 23:37:39 $ 9 9 * 10 10 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 33 33 psElemType type; 34 34 fftwf_plan plan; 35 35 36 36 /* got good image data? */ 37 37 if ( in == NULL ) { 38 psFree( out );39 return NULL;40 }41 42 type = in->type.type; 43 38 psFree( out ); 39 return NULL; 40 } 41 42 type = in->type.type; 43 44 44 if ( ( type != PS_TYPE_F32 ) && ( type != PS_TYPE_C32 ) ) { 45 psError( __func__, "Input image must be a 32-bit float or complex image (type=%d)",46 type );47 psFree( out );48 return NULL;49 }50 45 psError( __func__, "Input image must be a 32-bit float or complex image (type=%d)", 46 type ); 47 psFree( out ); 48 return NULL; 49 } 50 51 51 if ( type != PS_TYPE_C32 && direction == PS_FFT_REVERSE ) { 52 psError( __func__, "Input image must be complex image for reverse FFT (type=%d).",53 type );54 psFree( out );55 return NULL;56 57 }58 52 psError( __func__, "Input image must be complex image for reverse FFT (type=%d).", 53 type ); 54 psFree( out ); 55 return NULL; 56 57 } 58 59 59 if ( type != PS_TYPE_F32 && direction == PS_FFT_FORWARD ) { 60 psError( __func__, "Input image must be real image for forward FFT (type=%d).",61 type );62 psFree( out );63 return NULL;64 }65 60 psError( __func__, "Input image must be real image for forward FFT (type=%d).", 61 type ); 62 psFree( out ); 63 return NULL; 64 } 65 66 66 /* make sure the system-level wisdom information is imported. */ 67 67 if ( ! p_fftwWisdomImported ) { 68 fftwf_import_system_wisdom();69 p_fftwWisdomImported = true;70 }71 68 fftwf_import_system_wisdom(); 69 p_fftwWisdomImported = true; 70 } 71 72 72 numRows = in->numRows; 73 73 numCols = in->numCols; 74 74 75 75 out = psImageCopy( out, in, PS_TYPE_C32 ); 76 76 77 77 plan = fftwf_plan_dft_2d( numCols, numRows, 78 78 ( fftwf_complex* ) out->data.C32[ 0 ], … … 80 80 direction, 81 81 P_FFTW_PLAN_RIGOR ); 82 82 83 83 /* check if a plan exists now*/ 84 84 if ( plan == NULL ) { 85 psError( __func__, "Failed to create FFTW plan." );86 psFree( out );87 return NULL;88 }89 85 psError( __func__, "Failed to create FFTW plan." ); 86 psFree( out ); 87 return NULL; 88 } 89 90 90 /* finally, call FFTW with the plan made above */ 91 91 fftwf_execute( plan ); 92 92 93 93 fftwf_destroy_plan( plan ); 94 95 return out; 96 94 95 return out; 96 97 97 } 98 98 … … 103 103 unsigned int numCols; 104 104 unsigned int numRows; 105 106 107 if ( in == NULL ) { 108 psFree( out );109 return NULL;110 }111 105 106 107 if ( in == NULL ) { 108 psFree( out ); 109 return NULL; 110 } 111 112 112 type = in->type.type; 113 113 numCols = in->numCols; 114 114 numRows = in->numRows; 115 115 116 116 /* if not a complex number, this is logically just a copy */ 117 117 if ( ! PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 118 // Warn user, as this is probably not expected119 psLogMsg( __func__, PS_LOG_WARN, "Real portion of a non-Complex type called called for. "120 "Just an image copy was performed." );121 return psImageCopy( out, in, type );122 }123 118 // Warn user, as this is probably not expected 119 psLogMsg( __func__, PS_LOG_WARN, "Real portion of a non-Complex type called called for. " 120 "Just an image copy was performed." ); 121 return psImageCopy( out, in, type ); 122 } 123 124 124 if ( type == PS_TYPE_C32 ) { 125 psF32 * outRow; 126 psC32* inRow; 127 128 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F32 ); 129 for ( unsigned int row = 0;row < numRows;row++ ) { 130 outRow = out->data.F32[ row ]; 131 inRow = in->data.C32[ row ]; 132 133 for ( unsigned int col = 0;col < numCols;col++ ) { 134 outRow[ col ] = crealf( inRow[ col ] ); 135 } 136 } 137 } else if ( type == PS_TYPE_C64 ) { 125 psF32 * outRow; 126 psC32* inRow; 127 128 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F32 ); 129 for ( unsigned int row = 0;row < numRows;row++ ) { 130 outRow = out->data.F32[ row ]; 131 inRow = in->data.C32[ row ]; 132 133 for ( unsigned int col = 0;col < numCols;col++ ) { 134 outRow[ col ] = crealf( inRow[ col ] ); 135 } 136 } 137 } else 138 if ( type == PS_TYPE_C64 ) { 138 139 psF64 * outRow; 139 140 psC64* inRow; 140 141 141 142 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F64 ); 142 143 for ( unsigned int row = 0;row < numRows;row++ ) { 143 outRow = out->data.F64[ row ]; 144 inRow = in->data.C64[ row ]; 145 146 for ( unsigned int col = 0;col < numCols;col++ ) { 147 outRow[ col ] = creal( inRow[ col ] ); 148 } 144 outRow = out->data.F64[ row ]; 145 inRow = in->data.C64[ row ]; 146 147 for ( unsigned int col = 0;col < numCols;col++ ) { 148 outRow[ col ] = creal( inRow[ col ] ); 149 149 } 150 } 150 151 } else { 151 152 psError( __func__, "Can not extract real component from given image type (%d).", … … 154 155 return NULL; 155 156 } 156 157 157 158 return out; 158 159 } … … 163 164 unsigned int numCols; 164 165 unsigned int numRows; 165 166 167 if ( in == NULL ) { 168 psFree( out );169 return NULL;170 }171 166 167 168 if ( in == NULL ) { 169 psFree( out ); 170 return NULL; 171 } 172 172 173 type = in->type.type; 173 174 numCols = in->numCols; 174 175 numRows = in->numRows; 175 176 176 177 /* if not a complex number, this is logically just zeroed image of same size */ 177 178 if ( ! PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 178 // Warn user, as this is probably not expected179 psLogMsg( __func__, PS_LOG_WARN, "Imaginary portion of a non-Complex type called for. "180 "A zero image was returned." );181 out = psImageRecycle( out, numCols, numRows, type );182 memset( out->data.V[ 0 ], 0, PSELEMTYPE_SIZEOF( type ) * numCols * numRows );183 return out;184 }185 179 // Warn user, as this is probably not expected 180 psLogMsg( __func__, PS_LOG_WARN, "Imaginary portion of a non-Complex type called for. " 181 "A zero image was returned." ); 182 out = psImageRecycle( out, numCols, numRows, type ); 183 memset( out->data.V[ 0 ], 0, PSELEMTYPE_SIZEOF( type ) * numCols * numRows ); 184 return out; 185 } 186 186 187 if ( type == PS_TYPE_C32 ) { 187 psF32 * outRow; 188 psC32* inRow; 189 190 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F32 ); 191 for ( unsigned int row = 0;row < numRows;row++ ) { 192 outRow = out->data.F32[ row ]; 193 inRow = in->data.C32[ row ]; 194 195 for ( unsigned int col = 0;col < numCols;col++ ) { 196 outRow[ col ] = cimagf( inRow[ col ] ); 197 } 198 } 199 } else if ( type == PS_TYPE_C64 ) { 188 psF32 * outRow; 189 psC32* inRow; 190 191 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F32 ); 192 for ( unsigned int row = 0;row < numRows;row++ ) { 193 outRow = out->data.F32[ row ]; 194 inRow = in->data.C32[ row ]; 195 196 for ( unsigned int col = 0;col < numCols;col++ ) { 197 outRow[ col ] = cimagf( inRow[ col ] ); 198 } 199 } 200 } else 201 if ( type == PS_TYPE_C64 ) { 200 202 psF64 * outRow; 201 203 psC64* inRow; 202 204 203 205 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F64 ); 204 206 for ( unsigned int row = 0;row < numRows;row++ ) { 205 outRow = out->data.F64[ row ]; 206 inRow = in->data.C64[ row ]; 207 208 for ( unsigned int col = 0;col < numCols;col++ ) { 209 outRow[ col ] = cimag( inRow[ col ] ); 210 } 207 outRow = out->data.F64[ row ]; 208 inRow = in->data.C64[ row ]; 209 210 for ( unsigned int col = 0;col < numCols;col++ ) { 211 outRow[ col ] = cimag( inRow[ col ] ); 211 212 } 213 } 212 214 } else { 213 215 psError( __func__, "Can not extract imaginary component from given image type (%d).", … … 216 218 return NULL; 217 219 } 218 220 219 221 return out; 220 222 } … … 225 227 unsigned int numCols; 226 228 unsigned int numRows; 227 228 229 230 229 231 if ( real == NULL || imag == NULL ) { 230 psFree( out );231 return NULL;232 }233 232 psFree( out ); 233 return NULL; 234 } 235 234 236 type = real->type.type; 235 237 numCols = real->numCols; 236 238 numRows = real->numRows; 237 239 238 240 if ( imag->type.type != type ) { 239 psError( __func__, "The inputs to psImageComplex must be the same type." );240 psFree( out );241 return NULL;242 }243 241 psError( __func__, "The inputs to psImageComplex must be the same type." ); 242 psFree( out ); 243 return NULL; 244 } 245 244 246 if ( imag->numCols != numCols || 245 247 imag->numRows != numRows ) { 246 psError( __func__, "The inputs to psImageComplex must be the same dimensions." );247 psFree( out );248 return NULL;249 }250 248 psError( __func__, "The inputs to psImageComplex must be the same dimensions." ); 249 psFree( out ); 250 return NULL; 251 } 252 251 253 if ( PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 252 psError( __func__, "The inputs to psImageComplex can not be complex." );253 psFree( out );254 return NULL;255 }256 254 psError( __func__, "The inputs to psImageComplex can not be complex." ); 255 psFree( out ); 256 return NULL; 257 } 258 257 259 if ( type != PS_TYPE_F32 && type != PS_TYPE_F64 ) { 258 psError( __func__, "The input type to psImageComplex must be a floating point." );259 psFree( out );260 return NULL;261 }262 260 psError( __func__, "The input type to psImageComplex must be a floating point." ); 261 psFree( out ); 262 return NULL; 263 } 264 263 265 if ( type == PS_TYPE_F32 ) { 264 psC32 * outRow; 265 psF32* realRow; 266 psF32* imagRow; 267 268 out = psImageRecycle( out, numCols, numRows, PS_TYPE_C32 ); 269 270 for ( unsigned int row = 0;row < numRows;row++ ) { 271 outRow = out->data.C32[ row ]; 272 realRow = real->data.F32[ row ]; 273 imagRow = imag->data.F32[ row ]; 274 275 for ( unsigned int col = 0;col < numCols;col++ ) { 276 outRow[ col ] = realRow[ col ] + I * imagRow[ col ]; 277 } 278 } 279 } else if ( type == PS_TYPE_F64 ) { 266 psC32 * outRow; 267 psF32* realRow; 268 psF32* imagRow; 269 270 out = psImageRecycle( out, numCols, numRows, PS_TYPE_C32 ); 271 272 for ( unsigned int row = 0;row < numRows;row++ ) { 273 outRow = out->data.C32[ row ]; 274 realRow = real->data.F32[ row ]; 275 imagRow = imag->data.F32[ row ]; 276 277 for ( unsigned int col = 0;col < numCols;col++ ) { 278 outRow[ col ] = realRow[ col ] + I * imagRow[ col ]; 279 } 280 } 281 } else 282 if ( type == PS_TYPE_F64 ) { 280 283 psC64 * outRow; 281 284 psF64* realRow; 282 285 psF64* imagRow; 283 286 284 287 out = psImageRecycle( out, numCols, numRows, PS_TYPE_C64 ); 285 288 for ( unsigned int row = 0;row < numRows;row++ ) { 286 outRow = out->data.C64[ row ]; 287 realRow = real->data.F64[ row ]; 288 imagRow = imag->data.F64[ row ]; 289 290 for ( unsigned int col = 0;col < numCols;col++ ) { 291 outRow[ col ] = realRow[ col ] + I * imagRow[ col ]; 292 } 289 outRow = out->data.C64[ row ]; 290 realRow = real->data.F64[ row ]; 291 imagRow = imag->data.F64[ row ]; 292 293 for ( unsigned int col = 0;col < numCols;col++ ) { 294 outRow[ col ] = realRow[ col ] + I * imagRow[ col ]; 293 295 } 296 } 294 297 } else { 295 298 psError( __func__, "Can not merge real and imaginary portions for given image type (%d).", … … 298 301 return NULL; 299 302 } 300 303 301 304 return out; 302 305 } … … 307 310 unsigned int numCols; 308 311 unsigned int numRows; 309 310 311 if ( in == NULL ) { 312 psFree( out );313 return NULL;314 }315 312 313 314 if ( in == NULL ) { 315 psFree( out ); 316 return NULL; 317 } 318 316 319 type = in->type.type; 317 320 numCols = in->numCols; 318 321 numRows = in->numRows; 319 322 320 323 /* if not a complex number, this is logically just a image copy */ 321 324 if ( ! PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 322 // Warn user, as this is probably not expected323 psLogMsg( __func__, PS_LOG_WARN, "Complex Conjugate of a non-Complex type called for. "324 "Image copy was performed instead." );325 return psImageCopy( out, in, type );326 }327 325 // Warn user, as this is probably not expected 326 psLogMsg( __func__, PS_LOG_WARN, "Complex Conjugate of a non-Complex type called for. " 327 "Image copy was performed instead." ); 328 return psImageCopy( out, in, type ); 329 } 330 328 331 if ( type == PS_TYPE_C32 ) { 329 psC32 * outRow; 330 psC32* inRow; 331 332 out = psImageRecycle( out, numCols, numRows, PS_TYPE_C32 ); 333 for ( unsigned int row = 0;row < numRows;row++ ) { 334 outRow = out->data.C32[ row ]; 335 inRow = in->data.C32[ row ]; 336 337 for ( unsigned int col = 0;col < numCols;col++ ) { 338 outRow[ col ] = crealf( inRow[ col ] ) - I * cimagf( inRow[ col ] ); 339 } 340 } 341 } else if ( type == PS_TYPE_C64 ) { 332 psC32 * outRow; 333 psC32* inRow; 334 335 out = psImageRecycle( out, numCols, numRows, PS_TYPE_C32 ); 336 for ( unsigned int row = 0;row < numRows;row++ ) { 337 outRow = out->data.C32[ row ]; 338 inRow = in->data.C32[ row ]; 339 340 for ( unsigned int col = 0;col < numCols;col++ ) { 341 outRow[ col ] = crealf( inRow[ col ] ) - I * cimagf( inRow[ col ] ); 342 } 343 } 344 } else 345 if ( type == PS_TYPE_C64 ) { 342 346 psC64 * outRow; 343 347 psC64* inRow; 344 348 345 349 out = psImageRecycle( out, numCols, numRows, PS_TYPE_C64 ); 346 350 for ( unsigned int row = 0;row < numRows;row++ ) { 347 outRow = out->data.C64[ row ]; 348 inRow = in->data.C64[ row ]; 349 350 for ( unsigned int col = 0;col < numCols;col++ ) { 351 outRow[ col ] = creal( inRow[ col ] ) - I * cimag( inRow[ col ] ); 352 } 351 outRow = out->data.C64[ row ]; 352 inRow = in->data.C64[ row ]; 353 354 for ( unsigned int col = 0;col < numCols;col++ ) { 355 outRow[ col ] = creal( inRow[ col ] ) - I * cimag( inRow[ col ] ); 353 356 } 357 } 354 358 } else { 355 359 psError( __func__, "Can not compute complex conjugate for given image type (%d).", … … 358 362 return NULL; 359 363 } 360 364 361 365 return out; 362 366 } … … 368 372 unsigned int numRows; 369 373 int numElementsSquared; 370 371 if ( in == NULL ) { 372 psFree( out );373 return NULL;374 }375 374 375 if ( in == NULL ) { 376 psFree( out ); 377 return NULL; 378 } 379 376 380 type = in->type.type; 377 381 numCols = in->numCols; 378 382 numRows = in->numRows; 379 383 numElementsSquared = numCols * numCols * numRows * numRows; 380 384 381 385 /* if not a complex number, this is not implemented */ 382 386 if ( ! PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 383 psError( __func__, "Power Spectrum for non-complex inputs is not implemented." );384 psFree( out );385 return NULL;386 }387 387 psError( __func__, "Power Spectrum for non-complex inputs is not implemented." ); 388 psFree( out ); 389 return NULL; 390 } 391 388 392 if ( type == PS_TYPE_C32 ) { 389 psF32 * outRow; 390 psC32* inRow; 391 psF32 real; 392 psF32 imag; 393 394 395 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F32 ); 396 for ( unsigned int row = 0;row < numRows;row++ ) { 397 outRow = out->data.F32[ row ]; 398 inRow = in->data.C32[ row ]; 399 400 for ( unsigned int col = 0;col < numCols;col++ ) { 401 real = crealf( inRow[ col ] ); 402 imag = cimagf( inRow[ col ] ); 403 outRow[ col ] = ( real * real + imag * imag ) / numElementsSquared; 404 } 405 } 406 } else if ( type == PS_TYPE_C64 ) { 393 psF32 * outRow; 394 psC32* inRow; 395 psF32 real; 396 psF32 imag; 397 398 399 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F32 ); 400 for ( unsigned int row = 0;row < numRows;row++ ) { 401 outRow = out->data.F32[ row ]; 402 inRow = in->data.C32[ row ]; 403 404 for ( unsigned int col = 0;col < numCols;col++ ) { 405 real = crealf( inRow[ col ] ); 406 imag = cimagf( inRow[ col ] ); 407 outRow[ col ] = ( real * real + imag * imag ) / numElementsSquared; 408 } 409 } 410 } else 411 if ( type == PS_TYPE_C64 ) { 407 412 psF64 * outRow; 408 413 psC64* inRow; 409 414 psF64 real; 410 415 psF64 imag; 411 412 416 417 413 418 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F64 ); 414 419 for ( unsigned int row = 0;row < numRows;row++ ) { 415 outRow = out->data.F64[ row ]; 416 inRow = in->data.C64[ row ]; 417 418 for ( unsigned int col = 0;col < numCols;col++ ) { 419 real = crealf( inRow[ col ] ); 420 imag = cimagf( inRow[ col ] ); 421 outRow[ col ] = real * real + imag * imag / numElementsSquared; 422 } 420 outRow = out->data.F64[ row ]; 421 inRow = in->data.C64[ row ]; 422 423 for ( unsigned int col = 0;col < numCols;col++ ) { 424 real = crealf( inRow[ col ] ); 425 imag = cimagf( inRow[ col ] ); 426 outRow[ col ] = real * real + imag * imag / numElementsSquared; 423 427 } 428 } 424 429 } else { 425 430 psError( __func__, "Can not power spectrum for given image type (%d).", … … 428 433 return NULL; 429 434 } 430 431 return out; 432 435 436 return out; 437 433 438 } 434 439 … … 440 445 psElemType type; 441 446 fftwf_plan plan; 442 447 443 448 /* got good image data? */ 444 449 if ( in == NULL ) { 445 psFree( out );446 return NULL;447 }448 449 type = in->type.type; 450 450 psFree( out ); 451 return NULL; 452 } 453 454 type = in->type.type; 455 451 456 if ( ( type != PS_TYPE_F32 ) && ( type != PS_TYPE_C32 ) ) { 452 psError( __func__, "Input image must be a 32-bit float or complex image (type=%d)",453 type );454 psFree( out );455 return NULL;456 }457 457 psError( __func__, "Input image must be a 32-bit float or complex image (type=%d)", 458 type ); 459 psFree( out ); 460 return NULL; 461 } 462 458 463 if ( ( type != PS_TYPE_C32 ) && ( direction == PS_FFT_REVERSE ) ) { 459 psError( __func__, "Input image must be complex image for reverse FFT (type=%d).",460 type );461 psFree( out );462 return NULL;463 464 }465 464 psError( __func__, "Input image must be complex image for reverse FFT (type=%d).", 465 type ); 466 psFree( out ); 467 return NULL; 468 469 } 470 466 471 if ( ( type != PS_TYPE_F32 ) && ( direction == PS_FFT_FORWARD ) ) { 467 psError( __func__, "Input image must be real image for forward FFT (type=%d).",468 type );469 psFree( out );470 return NULL;471 }472 472 psError( __func__, "Input image must be real image for forward FFT (type=%d).", 473 type ); 474 psFree( out ); 475 return NULL; 476 } 477 473 478 /* make sure the system-level wisdom information is imported. */ 474 479 if ( ! p_fftwWisdomImported ) { 475 fftwf_import_system_wisdom();476 p_fftwWisdomImported = true;477 }478 480 fftwf_import_system_wisdom(); 481 p_fftwWisdomImported = true; 482 } 483 479 484 numElements = in->n; 480 485 481 486 out = psVectorRecycle( out, PS_TYPE_C32, numElements ); 482 487 out->n = numElements; 483 488 484 489 if ( type == PS_TYPE_F32 ) { 485 // need to convert to complex486 psC32 * outVec = out->data.C32;487 psF32* inVec = in->data.F32;488 for ( unsigned int i = 0;i < numElements;i++ ) {489 outVec[ i ] = inVec[ i ];490 }491 } else {492 psC32* outVec = out->data.C32;493 psC32* inVec = in->data.C32;494 for ( unsigned int i = 0;i < numElements;i++ ) {495 outVec[ i ] = inVec[ i ];496 }497 }498 490 // need to convert to complex 491 psC32 * outVec = out->data.C32; 492 psF32* inVec = in->data.F32; 493 for ( unsigned int i = 0;i < numElements;i++ ) { 494 outVec[ i ] = inVec[ i ]; 495 } 496 } else { 497 psC32* outVec = out->data.C32; 498 psC32* inVec = in->data.C32; 499 for ( unsigned int i = 0;i < numElements;i++ ) { 500 outVec[ i ] = inVec[ i ]; 501 } 502 } 503 499 504 plan = fftwf_plan_dft_1d( numElements, 500 505 ( fftwf_complex* ) out->data.C32, … … 502 507 direction, 503 508 P_FFTW_PLAN_RIGOR ); 504 509 505 510 /* check if a plan exists now*/ 506 511 if ( plan == NULL ) { 507 psError( __func__, "Failed to create FFTW plan." );508 psFree( out );509 return NULL;510 }511 512 psError( __func__, "Failed to create FFTW plan." ); 513 psFree( out ); 514 return NULL; 515 } 516 512 517 /* finally, call FFTW with the plan made above */ 513 518 fftwf_execute( plan ); 514 519 515 520 fftwf_destroy_plan( plan ); 516 521 517 522 return out; 518 523 } … … 523 528 psElemType type; 524 529 unsigned int numElements; 525 526 if ( in == NULL ) { 527 psFree( out );528 return NULL;529 }530 530 531 if ( in == NULL ) { 532 psFree( out ); 533 return NULL; 534 } 535 531 536 type = in->type.type; 532 537 numElements = in->n; 533 538 534 539 /* if not a complex number, this is logically just a copy */ 535 540 if ( ! PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 536 // Warn user, as this is probably not expected537 psLogMsg( __func__, PS_LOG_WARN, "Real portion of a non-Complex type called called for. "538 "Just a vector copy was performed." );539 out = psVectorRecycle( out, type, numElements );540 out->n = numElements;541 memcpy( out->data.V, in->data.V, numElements * PSELEMTYPE_SIZEOF( type ) );542 return out;543 }544 541 // Warn user, as this is probably not expected 542 psLogMsg( __func__, PS_LOG_WARN, "Real portion of a non-Complex type called called for. " 543 "Just a vector copy was performed." ); 544 out = psVectorRecycle( out, type, numElements ); 545 out->n = numElements; 546 memcpy( out->data.V, in->data.V, numElements * PSELEMTYPE_SIZEOF( type ) ); 547 return out; 548 } 549 545 550 if ( type == PS_TYPE_C32 ) { 546 psF32 * outVec;547 psC32* inVec = in->data.C32;548 549 out = psVectorRecycle( out, PS_TYPE_F32, numElements );550 out->n = numElements;551 outVec = out->data.F32;552 553 for ( unsigned int i = 0;i < numElements;i++ ) {554 outVec[ i ] = crealf( inVec[ i ] );555 }556 } else {557 psError( __func__, "Can not extract real component from given vector type (%d).",558 type );559 psFree( out );560 return NULL;561 }562 551 psF32 * outVec; 552 psC32* inVec = in->data.C32; 553 554 out = psVectorRecycle( out, PS_TYPE_F32, numElements ); 555 out->n = numElements; 556 outVec = out->data.F32; 557 558 for ( unsigned int i = 0;i < numElements;i++ ) { 559 outVec[ i ] = crealf( inVec[ i ] ); 560 } 561 } else { 562 psError( __func__, "Can not extract real component from given vector type (%d).", 563 type ); 564 psFree( out ); 565 return NULL; 566 } 567 563 568 return out; 564 569 } … … 568 573 psElemType type; 569 574 unsigned int numElements; 570 571 572 if ( in == NULL ) { 573 psFree( out );574 return NULL;575 }576 575 576 577 if ( in == NULL ) { 578 psFree( out ); 579 return NULL; 580 } 581 577 582 type = in->type.type; 578 583 numElements = in->n; 579 584 580 585 /* if not a complex number, this is logically just zeroed image of same size */ 581 586 if ( ! PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 582 // Warn user, as this is probably not expected583 psLogMsg( __func__, PS_LOG_WARN, "Imaginary portion of a non-Complex type called for. "584 "A zeroed vector was returned." );585 out = psVectorRecycle( out, type, numElements );586 out->n = numElements;587 memset( out->data.V, 0, PSELEMTYPE_SIZEOF( type ) * numElements );588 return out;589 }590 587 // Warn user, as this is probably not expected 588 psLogMsg( __func__, PS_LOG_WARN, "Imaginary portion of a non-Complex type called for. " 589 "A zeroed vector was returned." ); 590 out = psVectorRecycle( out, type, numElements ); 591 out->n = numElements; 592 memset( out->data.V, 0, PSELEMTYPE_SIZEOF( type ) * numElements ); 593 return out; 594 } 595 591 596 if ( type == PS_TYPE_C32 ) { 592 psF32 * outVec;593 psC32* inVec = in->data.C32;594 595 out = psVectorRecycle( out, PS_TYPE_F32, numElements );596 out->n = numElements;597 outVec = out->data.F32;598 599 for ( unsigned int i = 0;i < numElements;i++ ) {600 outVec[ i ] = cimagf( inVec[ i ] );601 }602 } else {603 psError( __func__, "Can not extract imaginary component from given vector type (%d).",604 type );605 psFree( out );606 return NULL;607 }608 597 psF32 * outVec; 598 psC32* inVec = in->data.C32; 599 600 out = psVectorRecycle( out, PS_TYPE_F32, numElements ); 601 out->n = numElements; 602 outVec = out->data.F32; 603 604 for ( unsigned int i = 0;i < numElements;i++ ) { 605 outVec[ i ] = cimagf( inVec[ i ] ); 606 } 607 } else { 608 psError( __func__, "Can not extract imaginary component from given vector type (%d).", 609 type ); 610 psFree( out ); 611 return NULL; 612 } 613 609 614 return out; 610 615 } … … 614 619 psElemType type; 615 620 unsigned int numElements; 616 617 621 622 618 623 if ( real == NULL || imag == NULL ) { 619 psFree( out );620 return NULL;621 }622 624 psFree( out ); 625 return NULL; 626 } 627 623 628 type = real->type.type; 624 629 if ( real->n < imag->n ) { 625 numElements = real->n;626 } else {627 numElements = imag->n;628 }629 630 numElements = real->n; 631 } else { 632 numElements = imag->n; 633 } 634 630 635 if ( imag->type.type != type ) { 631 psError( __func__, "The inputs to psVectorComplex must be the same type." );632 psFree( out );633 return NULL;634 }635 636 psError( __func__, "The inputs to psVectorComplex must be the same type." ); 637 psFree( out ); 638 return NULL; 639 } 640 636 641 if ( PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 637 psError( __func__, "The inputs to psVectorComplex can not be complex." );638 psFree( out );639 return NULL;640 }641 642 psError( __func__, "The inputs to psVectorComplex can not be complex." ); 643 psFree( out ); 644 return NULL; 645 } 646 642 647 if ( type == PS_TYPE_F32 ) { 643 psC32 * outVec;644 psF32* realVec = real->data.F32;645 psF32* imagVec = imag->data.F32;646 647 out = psVectorRecycle( out, PS_TYPE_C32, numElements );648 out->n = numElements;649 outVec = out->data.C32;650 651 for ( unsigned int i = 0;i < numElements;i++ ) {652 outVec[ i ] = realVec[ i ] + I * imagVec[ i ];653 }654 } else {655 psError( __func__, "Can not merge real and imaginary portions for given vector type (%d).",656 type );657 psFree( out );658 return NULL;659 }660 648 psC32 * outVec; 649 psF32* realVec = real->data.F32; 650 psF32* imagVec = imag->data.F32; 651 652 out = psVectorRecycle( out, PS_TYPE_C32, numElements ); 653 out->n = numElements; 654 outVec = out->data.C32; 655 656 for ( unsigned int i = 0;i < numElements;i++ ) { 657 outVec[ i ] = realVec[ i ] + I * imagVec[ i ]; 658 } 659 } else { 660 psError( __func__, "Can not merge real and imaginary portions for given vector type (%d).", 661 type ); 662 psFree( out ); 663 return NULL; 664 } 665 661 666 return out; 662 667 } … … 666 671 psElemType type; 667 672 unsigned int numElements; 668 669 670 if ( in == NULL ) { 671 psFree( out );672 return NULL;673 }674 673 674 675 if ( in == NULL ) { 676 psFree( out ); 677 return NULL; 678 } 679 675 680 type = in->type.type; 676 681 numElements = in->n; 677 682 678 683 /* if not a complex number, this is logically just a image copy */ 679 684 if ( ! PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 680 // Warn user, as this is probably not expected681 psLogMsg( __func__, PS_LOG_WARN, "Complex Conjugate of a non-Complex type called for. "682 "Vector copy was performed instead." );683 684 out = psVectorRecycle( out, type, numElements );685 out->n = numElements;686 memcpy( out->data.V, in->data.V, PSELEMTYPE_SIZEOF( type ) * numElements );687 return out;688 }689 685 // Warn user, as this is probably not expected 686 psLogMsg( __func__, PS_LOG_WARN, "Complex Conjugate of a non-Complex type called for. " 687 "Vector copy was performed instead." ); 688 689 out = psVectorRecycle( out, type, numElements ); 690 out->n = numElements; 691 memcpy( out->data.V, in->data.V, PSELEMTYPE_SIZEOF( type ) * numElements ); 692 return out; 693 } 694 690 695 if ( type == PS_TYPE_C32 ) { 691 psC32 * outVec;692 psC32* inVec = in->data.C32;693 694 out = psVectorRecycle( out, PS_TYPE_C32, numElements );695 out->n = numElements;696 outVec = out->data.C32;697 698 for ( unsigned int i = 0;i < numElements;i++ ) {699 outVec[ i ] = crealf( inVec[ i ] ) - I * cimagf( inVec[ i ] );700 }701 } else {702 psError( __func__, "Can not compute complex conjugate for given vector type (%d).",703 type );704 psFree( out );705 return NULL;706 }707 696 psC32 * outVec; 697 psC32* inVec = in->data.C32; 698 699 out = psVectorRecycle( out, PS_TYPE_C32, numElements ); 700 out->n = numElements; 701 outVec = out->data.C32; 702 703 for ( unsigned int i = 0;i < numElements;i++ ) { 704 outVec[ i ] = crealf( inVec[ i ] ) - I * cimagf( inVec[ i ] ); 705 } 706 } else { 707 psError( __func__, "Can not compute complex conjugate for given vector type (%d).", 708 type ); 709 psFree( out ); 710 return NULL; 711 } 712 708 713 return out; 709 714 } … … 716 721 unsigned int inHalfNumElements; 717 722 unsigned int inNumElementsSquared; 718 719 if ( in == NULL ) { 720 psFree( out );721 return NULL;722 }723 723 724 if ( in == NULL ) { 725 psFree( out ); 726 return NULL; 727 } 728 724 729 type = in->type.type; 725 730 inNumElements = in->n; … … 727 732 inHalfNumElements = inNumElements / 2; 728 733 outNumElements = inHalfNumElements + 1; 729 734 730 735 /* if not a complex number, this is not implemented */ 731 736 if ( ! PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 732 psError( __func__, "Power Spectrum for non-complex inputs is not implemented." );733 psFree( out );734 return NULL;735 }736 737 psError( __func__, "Power Spectrum for non-complex inputs is not implemented." ); 738 psFree( out ); 739 return NULL; 740 } 741 737 742 if ( type == PS_TYPE_C32 ) { 738 psF32 * outVec;739 psC32* inVec = in->data.C32;740 psF32 inAbs1;741 psF32 inAbs2;742 743 out = psVectorRecycle( out, PS_TYPE_F32, outNumElements );744 out->n = outNumElements;745 outVec = out->data.F32;746 747 // from ADD: P_0 = |C_0|^2/N^2748 inAbs1 = cabsf( inVec[ 0 ] );749 outVec[ 0 ] = inAbs1 * inAbs1 / inNumElementsSquared;750 751 // from ADD: P_j = (|C_j|^2+|C_N-j|^2)/N^2, where j = 1,2,...,(N/2-1)752 for ( unsigned int i = 1;i < inHalfNumElements;i++ ) {753 inAbs1 = cabsf( inVec[ i ] );754 inAbs2 = cabsf( inVec[ inNumElements - i ] );755 outVec[ i ] = ( inAbs1 * inAbs1 + inAbs2 * inAbs2 ) / inNumElementsSquared;756 }757 758 // from ADD: P_N/2 = |C_N/2|^2/N^2759 inAbs1 = cabsf( inVec[ inHalfNumElements ] );760 outVec[ inHalfNumElements ] = inAbs1 * inAbs1 / inNumElementsSquared;761 } else {762 psError( __func__, "Can not power spectrum for given vector type (%d).",763 type );764 psFree( out );765 return NULL;766 }767 768 return out; 769 770 } 743 psF32 * outVec; 744 psC32* inVec = in->data.C32; 745 psF32 inAbs1; 746 psF32 inAbs2; 747 748 out = psVectorRecycle( out, PS_TYPE_F32, outNumElements ); 749 out->n = outNumElements; 750 outVec = out->data.F32; 751 752 // from ADD: P_0 = |C_0|^2/N^2 753 inAbs1 = cabsf( inVec[ 0 ] ); 754 outVec[ 0 ] = inAbs1 * inAbs1 / inNumElementsSquared; 755 756 // from ADD: P_j = (|C_j|^2+|C_N-j|^2)/N^2, where j = 1,2,...,(N/2-1) 757 for ( unsigned int i = 1;i < inHalfNumElements;i++ ) { 758 inAbs1 = cabsf( inVec[ i ] ); 759 inAbs2 = cabsf( inVec[ inNumElements - i ] ); 760 outVec[ i ] = ( inAbs1 * inAbs1 + inAbs2 * inAbs2 ) / inNumElementsSquared; 761 } 762 763 // from ADD: P_N/2 = |C_N/2|^2/N^2 764 inAbs1 = cabsf( inVec[ inHalfNumElements ] ); 765 outVec[ inHalfNumElements ] = inAbs1 * inAbs1 / inNumElementsSquared; 766 } else { 767 psError( __func__, "Can not power spectrum for given vector type (%d).", 768 type ); 769 psFree( out ); 770 return NULL; 771 } 772 773 return out; 774 775 } -
trunk/psLib/src/dataManip/psVectorFFT.h
r974 r1385 7 7 * @author Robert DeSonia, MHPCC 8 8 * 9 * @version $Revision: 1. 6$ $Name: not supported by cvs2svn $10 * @date $Date: 2004-0 6-10 01:58:06$9 * @version $Revision: 1.7 $ $Name: not supported by cvs2svn $ 10 * @date $Date: 2004-08-04 23:37:39 $ 11 11 * 12 12 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/fft/psVectorFFT.c
r1366 r1385 5 5 * @author Robert DeSonia, MHPCC 6 6 * 7 * @version $Revision: 1.1 5$ $Name: not supported by cvs2svn $8 * @date $Date: 2004-08-0 2 19:43:59 $7 * @version $Revision: 1.16 $ $Name: not supported by cvs2svn $ 8 * @date $Date: 2004-08-04 23:37:39 $ 9 9 * 10 10 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 33 33 psElemType type; 34 34 fftwf_plan plan; 35 35 36 36 /* got good image data? */ 37 37 if ( in == NULL ) { 38 psFree( out );39 return NULL;40 }41 42 type = in->type.type; 43 38 psFree( out ); 39 return NULL; 40 } 41 42 type = in->type.type; 43 44 44 if ( ( type != PS_TYPE_F32 ) && ( type != PS_TYPE_C32 ) ) { 45 psError( __func__, "Input image must be a 32-bit float or complex image (type=%d)",46 type );47 psFree( out );48 return NULL;49 }50 45 psError( __func__, "Input image must be a 32-bit float or complex image (type=%d)", 46 type ); 47 psFree( out ); 48 return NULL; 49 } 50 51 51 if ( type != PS_TYPE_C32 && direction == PS_FFT_REVERSE ) { 52 psError( __func__, "Input image must be complex image for reverse FFT (type=%d).",53 type );54 psFree( out );55 return NULL;56 57 }58 52 psError( __func__, "Input image must be complex image for reverse FFT (type=%d).", 53 type ); 54 psFree( out ); 55 return NULL; 56 57 } 58 59 59 if ( type != PS_TYPE_F32 && direction == PS_FFT_FORWARD ) { 60 psError( __func__, "Input image must be real image for forward FFT (type=%d).",61 type );62 psFree( out );63 return NULL;64 }65 60 psError( __func__, "Input image must be real image for forward FFT (type=%d).", 61 type ); 62 psFree( out ); 63 return NULL; 64 } 65 66 66 /* make sure the system-level wisdom information is imported. */ 67 67 if ( ! p_fftwWisdomImported ) { 68 fftwf_import_system_wisdom();69 p_fftwWisdomImported = true;70 }71 68 fftwf_import_system_wisdom(); 69 p_fftwWisdomImported = true; 70 } 71 72 72 numRows = in->numRows; 73 73 numCols = in->numCols; 74 74 75 75 out = psImageCopy( out, in, PS_TYPE_C32 ); 76 76 77 77 plan = fftwf_plan_dft_2d( numCols, numRows, 78 78 ( fftwf_complex* ) out->data.C32[ 0 ], … … 80 80 direction, 81 81 P_FFTW_PLAN_RIGOR ); 82 82 83 83 /* check if a plan exists now*/ 84 84 if ( plan == NULL ) { 85 psError( __func__, "Failed to create FFTW plan." );86 psFree( out );87 return NULL;88 }89 85 psError( __func__, "Failed to create FFTW plan." ); 86 psFree( out ); 87 return NULL; 88 } 89 90 90 /* finally, call FFTW with the plan made above */ 91 91 fftwf_execute( plan ); 92 92 93 93 fftwf_destroy_plan( plan ); 94 95 return out; 96 94 95 return out; 96 97 97 } 98 98 … … 103 103 unsigned int numCols; 104 104 unsigned int numRows; 105 106 107 if ( in == NULL ) { 108 psFree( out );109 return NULL;110 }111 105 106 107 if ( in == NULL ) { 108 psFree( out ); 109 return NULL; 110 } 111 112 112 type = in->type.type; 113 113 numCols = in->numCols; 114 114 numRows = in->numRows; 115 115 116 116 /* if not a complex number, this is logically just a copy */ 117 117 if ( ! PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 118 // Warn user, as this is probably not expected119 psLogMsg( __func__, PS_LOG_WARN, "Real portion of a non-Complex type called called for. "120 "Just an image copy was performed." );121 return psImageCopy( out, in, type );122 }123 118 // Warn user, as this is probably not expected 119 psLogMsg( __func__, PS_LOG_WARN, "Real portion of a non-Complex type called called for. " 120 "Just an image copy was performed." ); 121 return psImageCopy( out, in, type ); 122 } 123 124 124 if ( type == PS_TYPE_C32 ) { 125 psF32 * outRow; 126 psC32* inRow; 127 128 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F32 ); 129 for ( unsigned int row = 0;row < numRows;row++ ) { 130 outRow = out->data.F32[ row ]; 131 inRow = in->data.C32[ row ]; 132 133 for ( unsigned int col = 0;col < numCols;col++ ) { 134 outRow[ col ] = crealf( inRow[ col ] ); 135 } 136 } 137 } else if ( type == PS_TYPE_C64 ) { 125 psF32 * outRow; 126 psC32* inRow; 127 128 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F32 ); 129 for ( unsigned int row = 0;row < numRows;row++ ) { 130 outRow = out->data.F32[ row ]; 131 inRow = in->data.C32[ row ]; 132 133 for ( unsigned int col = 0;col < numCols;col++ ) { 134 outRow[ col ] = crealf( inRow[ col ] ); 135 } 136 } 137 } else 138 if ( type == PS_TYPE_C64 ) { 138 139 psF64 * outRow; 139 140 psC64* inRow; 140 141 141 142 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F64 ); 142 143 for ( unsigned int row = 0;row < numRows;row++ ) { 143 outRow = out->data.F64[ row ]; 144 inRow = in->data.C64[ row ]; 145 146 for ( unsigned int col = 0;col < numCols;col++ ) { 147 outRow[ col ] = creal( inRow[ col ] ); 148 } 144 outRow = out->data.F64[ row ]; 145 inRow = in->data.C64[ row ]; 146 147 for ( unsigned int col = 0;col < numCols;col++ ) { 148 outRow[ col ] = creal( inRow[ col ] ); 149 149 } 150 } 150 151 } else { 151 152 psError( __func__, "Can not extract real component from given image type (%d).", … … 154 155 return NULL; 155 156 } 156 157 157 158 return out; 158 159 } … … 163 164 unsigned int numCols; 164 165 unsigned int numRows; 165 166 167 if ( in == NULL ) { 168 psFree( out );169 return NULL;170 }171 166 167 168 if ( in == NULL ) { 169 psFree( out ); 170 return NULL; 171 } 172 172 173 type = in->type.type; 173 174 numCols = in->numCols; 174 175 numRows = in->numRows; 175 176 176 177 /* if not a complex number, this is logically just zeroed image of same size */ 177 178 if ( ! PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 178 // Warn user, as this is probably not expected179 psLogMsg( __func__, PS_LOG_WARN, "Imaginary portion of a non-Complex type called for. "180 "A zero image was returned." );181 out = psImageRecycle( out, numCols, numRows, type );182 memset( out->data.V[ 0 ], 0, PSELEMTYPE_SIZEOF( type ) * numCols * numRows );183 return out;184 }185 179 // Warn user, as this is probably not expected 180 psLogMsg( __func__, PS_LOG_WARN, "Imaginary portion of a non-Complex type called for. " 181 "A zero image was returned." ); 182 out = psImageRecycle( out, numCols, numRows, type ); 183 memset( out->data.V[ 0 ], 0, PSELEMTYPE_SIZEOF( type ) * numCols * numRows ); 184 return out; 185 } 186 186 187 if ( type == PS_TYPE_C32 ) { 187 psF32 * outRow; 188 psC32* inRow; 189 190 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F32 ); 191 for ( unsigned int row = 0;row < numRows;row++ ) { 192 outRow = out->data.F32[ row ]; 193 inRow = in->data.C32[ row ]; 194 195 for ( unsigned int col = 0;col < numCols;col++ ) { 196 outRow[ col ] = cimagf( inRow[ col ] ); 197 } 198 } 199 } else if ( type == PS_TYPE_C64 ) { 188 psF32 * outRow; 189 psC32* inRow; 190 191 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F32 ); 192 for ( unsigned int row = 0;row < numRows;row++ ) { 193 outRow = out->data.F32[ row ]; 194 inRow = in->data.C32[ row ]; 195 196 for ( unsigned int col = 0;col < numCols;col++ ) { 197 outRow[ col ] = cimagf( inRow[ col ] ); 198 } 199 } 200 } else 201 if ( type == PS_TYPE_C64 ) { 200 202 psF64 * outRow; 201 203 psC64* inRow; 202 204 203 205 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F64 ); 204 206 for ( unsigned int row = 0;row < numRows;row++ ) { 205 outRow = out->data.F64[ row ]; 206 inRow = in->data.C64[ row ]; 207 208 for ( unsigned int col = 0;col < numCols;col++ ) { 209 outRow[ col ] = cimag( inRow[ col ] ); 210 } 207 outRow = out->data.F64[ row ]; 208 inRow = in->data.C64[ row ]; 209 210 for ( unsigned int col = 0;col < numCols;col++ ) { 211 outRow[ col ] = cimag( inRow[ col ] ); 211 212 } 213 } 212 214 } else { 213 215 psError( __func__, "Can not extract imaginary component from given image type (%d).", … … 216 218 return NULL; 217 219 } 218 220 219 221 return out; 220 222 } … … 225 227 unsigned int numCols; 226 228 unsigned int numRows; 227 228 229 230 229 231 if ( real == NULL || imag == NULL ) { 230 psFree( out );231 return NULL;232 }233 232 psFree( out ); 233 return NULL; 234 } 235 234 236 type = real->type.type; 235 237 numCols = real->numCols; 236 238 numRows = real->numRows; 237 239 238 240 if ( imag->type.type != type ) { 239 psError( __func__, "The inputs to psImageComplex must be the same type." );240 psFree( out );241 return NULL;242 }243 241 psError( __func__, "The inputs to psImageComplex must be the same type." ); 242 psFree( out ); 243 return NULL; 244 } 245 244 246 if ( imag->numCols != numCols || 245 247 imag->numRows != numRows ) { 246 psError( __func__, "The inputs to psImageComplex must be the same dimensions." );247 psFree( out );248 return NULL;249 }250 248 psError( __func__, "The inputs to psImageComplex must be the same dimensions." ); 249 psFree( out ); 250 return NULL; 251 } 252 251 253 if ( PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 252 psError( __func__, "The inputs to psImageComplex can not be complex." );253 psFree( out );254 return NULL;255 }256 254 psError( __func__, "The inputs to psImageComplex can not be complex." ); 255 psFree( out ); 256 return NULL; 257 } 258 257 259 if ( type != PS_TYPE_F32 && type != PS_TYPE_F64 ) { 258 psError( __func__, "The input type to psImageComplex must be a floating point." );259 psFree( out );260 return NULL;261 }262 260 psError( __func__, "The input type to psImageComplex must be a floating point." ); 261 psFree( out ); 262 return NULL; 263 } 264 263 265 if ( type == PS_TYPE_F32 ) { 264 psC32 * outRow; 265 psF32* realRow; 266 psF32* imagRow; 267 268 out = psImageRecycle( out, numCols, numRows, PS_TYPE_C32 ); 269 270 for ( unsigned int row = 0;row < numRows;row++ ) { 271 outRow = out->data.C32[ row ]; 272 realRow = real->data.F32[ row ]; 273 imagRow = imag->data.F32[ row ]; 274 275 for ( unsigned int col = 0;col < numCols;col++ ) { 276 outRow[ col ] = realRow[ col ] + I * imagRow[ col ]; 277 } 278 } 279 } else if ( type == PS_TYPE_F64 ) { 266 psC32 * outRow; 267 psF32* realRow; 268 psF32* imagRow; 269 270 out = psImageRecycle( out, numCols, numRows, PS_TYPE_C32 ); 271 272 for ( unsigned int row = 0;row < numRows;row++ ) { 273 outRow = out->data.C32[ row ]; 274 realRow = real->data.F32[ row ]; 275 imagRow = imag->data.F32[ row ]; 276 277 for ( unsigned int col = 0;col < numCols;col++ ) { 278 outRow[ col ] = realRow[ col ] + I * imagRow[ col ]; 279 } 280 } 281 } else 282 if ( type == PS_TYPE_F64 ) { 280 283 psC64 * outRow; 281 284 psF64* realRow; 282 285 psF64* imagRow; 283 286 284 287 out = psImageRecycle( out, numCols, numRows, PS_TYPE_C64 ); 285 288 for ( unsigned int row = 0;row < numRows;row++ ) { 286 outRow = out->data.C64[ row ]; 287 realRow = real->data.F64[ row ]; 288 imagRow = imag->data.F64[ row ]; 289 290 for ( unsigned int col = 0;col < numCols;col++ ) { 291 outRow[ col ] = realRow[ col ] + I * imagRow[ col ]; 292 } 289 outRow = out->data.C64[ row ]; 290 realRow = real->data.F64[ row ]; 291 imagRow = imag->data.F64[ row ]; 292 293 for ( unsigned int col = 0;col < numCols;col++ ) { 294 outRow[ col ] = realRow[ col ] + I * imagRow[ col ]; 293 295 } 296 } 294 297 } else { 295 298 psError( __func__, "Can not merge real and imaginary portions for given image type (%d).", … … 298 301 return NULL; 299 302 } 300 303 301 304 return out; 302 305 } … … 307 310 unsigned int numCols; 308 311 unsigned int numRows; 309 310 311 if ( in == NULL ) { 312 psFree( out );313 return NULL;314 }315 312 313 314 if ( in == NULL ) { 315 psFree( out ); 316 return NULL; 317 } 318 316 319 type = in->type.type; 317 320 numCols = in->numCols; 318 321 numRows = in->numRows; 319 322 320 323 /* if not a complex number, this is logically just a image copy */ 321 324 if ( ! PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 322 // Warn user, as this is probably not expected323 psLogMsg( __func__, PS_LOG_WARN, "Complex Conjugate of a non-Complex type called for. "324 "Image copy was performed instead." );325 return psImageCopy( out, in, type );326 }327 325 // Warn user, as this is probably not expected 326 psLogMsg( __func__, PS_LOG_WARN, "Complex Conjugate of a non-Complex type called for. " 327 "Image copy was performed instead." ); 328 return psImageCopy( out, in, type ); 329 } 330 328 331 if ( type == PS_TYPE_C32 ) { 329 psC32 * outRow; 330 psC32* inRow; 331 332 out = psImageRecycle( out, numCols, numRows, PS_TYPE_C32 ); 333 for ( unsigned int row = 0;row < numRows;row++ ) { 334 outRow = out->data.C32[ row ]; 335 inRow = in->data.C32[ row ]; 336 337 for ( unsigned int col = 0;col < numCols;col++ ) { 338 outRow[ col ] = crealf( inRow[ col ] ) - I * cimagf( inRow[ col ] ); 339 } 340 } 341 } else if ( type == PS_TYPE_C64 ) { 332 psC32 * outRow; 333 psC32* inRow; 334 335 out = psImageRecycle( out, numCols, numRows, PS_TYPE_C32 ); 336 for ( unsigned int row = 0;row < numRows;row++ ) { 337 outRow = out->data.C32[ row ]; 338 inRow = in->data.C32[ row ]; 339 340 for ( unsigned int col = 0;col < numCols;col++ ) { 341 outRow[ col ] = crealf( inRow[ col ] ) - I * cimagf( inRow[ col ] ); 342 } 343 } 344 } else 345 if ( type == PS_TYPE_C64 ) { 342 346 psC64 * outRow; 343 347 psC64* inRow; 344 348 345 349 out = psImageRecycle( out, numCols, numRows, PS_TYPE_C64 ); 346 350 for ( unsigned int row = 0;row < numRows;row++ ) { 347 outRow = out->data.C64[ row ]; 348 inRow = in->data.C64[ row ]; 349 350 for ( unsigned int col = 0;col < numCols;col++ ) { 351 outRow[ col ] = creal( inRow[ col ] ) - I * cimag( inRow[ col ] ); 352 } 351 outRow = out->data.C64[ row ]; 352 inRow = in->data.C64[ row ]; 353 354 for ( unsigned int col = 0;col < numCols;col++ ) { 355 outRow[ col ] = creal( inRow[ col ] ) - I * cimag( inRow[ col ] ); 353 356 } 357 } 354 358 } else { 355 359 psError( __func__, "Can not compute complex conjugate for given image type (%d).", … … 358 362 return NULL; 359 363 } 360 364 361 365 return out; 362 366 } … … 368 372 unsigned int numRows; 369 373 int numElementsSquared; 370 371 if ( in == NULL ) { 372 psFree( out );373 return NULL;374 }375 374 375 if ( in == NULL ) { 376 psFree( out ); 377 return NULL; 378 } 379 376 380 type = in->type.type; 377 381 numCols = in->numCols; 378 382 numRows = in->numRows; 379 383 numElementsSquared = numCols * numCols * numRows * numRows; 380 384 381 385 /* if not a complex number, this is not implemented */ 382 386 if ( ! PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 383 psError( __func__, "Power Spectrum for non-complex inputs is not implemented." );384 psFree( out );385 return NULL;386 }387 387 psError( __func__, "Power Spectrum for non-complex inputs is not implemented." ); 388 psFree( out ); 389 return NULL; 390 } 391 388 392 if ( type == PS_TYPE_C32 ) { 389 psF32 * outRow; 390 psC32* inRow; 391 psF32 real; 392 psF32 imag; 393 394 395 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F32 ); 396 for ( unsigned int row = 0;row < numRows;row++ ) { 397 outRow = out->data.F32[ row ]; 398 inRow = in->data.C32[ row ]; 399 400 for ( unsigned int col = 0;col < numCols;col++ ) { 401 real = crealf( inRow[ col ] ); 402 imag = cimagf( inRow[ col ] ); 403 outRow[ col ] = ( real * real + imag * imag ) / numElementsSquared; 404 } 405 } 406 } else if ( type == PS_TYPE_C64 ) { 393 psF32 * outRow; 394 psC32* inRow; 395 psF32 real; 396 psF32 imag; 397 398 399 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F32 ); 400 for ( unsigned int row = 0;row < numRows;row++ ) { 401 outRow = out->data.F32[ row ]; 402 inRow = in->data.C32[ row ]; 403 404 for ( unsigned int col = 0;col < numCols;col++ ) { 405 real = crealf( inRow[ col ] ); 406 imag = cimagf( inRow[ col ] ); 407 outRow[ col ] = ( real * real + imag * imag ) / numElementsSquared; 408 } 409 } 410 } else 411 if ( type == PS_TYPE_C64 ) { 407 412 psF64 * outRow; 408 413 psC64* inRow; 409 414 psF64 real; 410 415 psF64 imag; 411 412 416 417 413 418 out = psImageRecycle( out, numCols, numRows, PS_TYPE_F64 ); 414 419 for ( unsigned int row = 0;row < numRows;row++ ) { 415 outRow = out->data.F64[ row ]; 416 inRow = in->data.C64[ row ]; 417 418 for ( unsigned int col = 0;col < numCols;col++ ) { 419 real = crealf( inRow[ col ] ); 420 imag = cimagf( inRow[ col ] ); 421 outRow[ col ] = real * real + imag * imag / numElementsSquared; 422 } 420 outRow = out->data.F64[ row ]; 421 inRow = in->data.C64[ row ]; 422 423 for ( unsigned int col = 0;col < numCols;col++ ) { 424 real = crealf( inRow[ col ] ); 425 imag = cimagf( inRow[ col ] ); 426 outRow[ col ] = real * real + imag * imag / numElementsSquared; 423 427 } 428 } 424 429 } else { 425 430 psError( __func__, "Can not power spectrum for given image type (%d).", … … 428 433 return NULL; 429 434 } 430 431 return out; 432 435 436 return out; 437 433 438 } 434 439 … … 440 445 psElemType type; 441 446 fftwf_plan plan; 442 447 443 448 /* got good image data? */ 444 449 if ( in == NULL ) { 445 psFree( out );446 return NULL;447 }448 449 type = in->type.type; 450 450 psFree( out ); 451 return NULL; 452 } 453 454 type = in->type.type; 455 451 456 if ( ( type != PS_TYPE_F32 ) && ( type != PS_TYPE_C32 ) ) { 452 psError( __func__, "Input image must be a 32-bit float or complex image (type=%d)",453 type );454 psFree( out );455 return NULL;456 }457 457 psError( __func__, "Input image must be a 32-bit float or complex image (type=%d)", 458 type ); 459 psFree( out ); 460 return NULL; 461 } 462 458 463 if ( ( type != PS_TYPE_C32 ) && ( direction == PS_FFT_REVERSE ) ) { 459 psError( __func__, "Input image must be complex image for reverse FFT (type=%d).",460 type );461 psFree( out );462 return NULL;463 464 }465 464 psError( __func__, "Input image must be complex image for reverse FFT (type=%d).", 465 type ); 466 psFree( out ); 467 return NULL; 468 469 } 470 466 471 if ( ( type != PS_TYPE_F32 ) && ( direction == PS_FFT_FORWARD ) ) { 467 psError( __func__, "Input image must be real image for forward FFT (type=%d).",468 type );469 psFree( out );470 return NULL;471 }472 472 psError( __func__, "Input image must be real image for forward FFT (type=%d).", 473 type ); 474 psFree( out ); 475 return NULL; 476 } 477 473 478 /* make sure the system-level wisdom information is imported. */ 474 479 if ( ! p_fftwWisdomImported ) { 475 fftwf_import_system_wisdom();476 p_fftwWisdomImported = true;477 }478 480 fftwf_import_system_wisdom(); 481 p_fftwWisdomImported = true; 482 } 483 479 484 numElements = in->n; 480 485 481 486 out = psVectorRecycle( out, PS_TYPE_C32, numElements ); 482 487 out->n = numElements; 483 488 484 489 if ( type == PS_TYPE_F32 ) { 485 // need to convert to complex486 psC32 * outVec = out->data.C32;487 psF32* inVec = in->data.F32;488 for ( unsigned int i = 0;i < numElements;i++ ) {489 outVec[ i ] = inVec[ i ];490 }491 } else {492 psC32* outVec = out->data.C32;493 psC32* inVec = in->data.C32;494 for ( unsigned int i = 0;i < numElements;i++ ) {495 outVec[ i ] = inVec[ i ];496 }497 }498 490 // need to convert to complex 491 psC32 * outVec = out->data.C32; 492 psF32* inVec = in->data.F32; 493 for ( unsigned int i = 0;i < numElements;i++ ) { 494 outVec[ i ] = inVec[ i ]; 495 } 496 } else { 497 psC32* outVec = out->data.C32; 498 psC32* inVec = in->data.C32; 499 for ( unsigned int i = 0;i < numElements;i++ ) { 500 outVec[ i ] = inVec[ i ]; 501 } 502 } 503 499 504 plan = fftwf_plan_dft_1d( numElements, 500 505 ( fftwf_complex* ) out->data.C32, … … 502 507 direction, 503 508 P_FFTW_PLAN_RIGOR ); 504 509 505 510 /* check if a plan exists now*/ 506 511 if ( plan == NULL ) { 507 psError( __func__, "Failed to create FFTW plan." );508 psFree( out );509 return NULL;510 }511 512 psError( __func__, "Failed to create FFTW plan." ); 513 psFree( out ); 514 return NULL; 515 } 516 512 517 /* finally, call FFTW with the plan made above */ 513 518 fftwf_execute( plan ); 514 519 515 520 fftwf_destroy_plan( plan ); 516 521 517 522 return out; 518 523 } … … 523 528 psElemType type; 524 529 unsigned int numElements; 525 526 if ( in == NULL ) { 527 psFree( out );528 return NULL;529 }530 530 531 if ( in == NULL ) { 532 psFree( out ); 533 return NULL; 534 } 535 531 536 type = in->type.type; 532 537 numElements = in->n; 533 538 534 539 /* if not a complex number, this is logically just a copy */ 535 540 if ( ! PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 536 // Warn user, as this is probably not expected537 psLogMsg( __func__, PS_LOG_WARN, "Real portion of a non-Complex type called called for. "538 "Just a vector copy was performed." );539 out = psVectorRecycle( out, type, numElements );540 out->n = numElements;541 memcpy( out->data.V, in->data.V, numElements * PSELEMTYPE_SIZEOF( type ) );542 return out;543 }544 541 // Warn user, as this is probably not expected 542 psLogMsg( __func__, PS_LOG_WARN, "Real portion of a non-Complex type called called for. " 543 "Just a vector copy was performed." ); 544 out = psVectorRecycle( out, type, numElements ); 545 out->n = numElements; 546 memcpy( out->data.V, in->data.V, numElements * PSELEMTYPE_SIZEOF( type ) ); 547 return out; 548 } 549 545 550 if ( type == PS_TYPE_C32 ) { 546 psF32 * outVec;547 psC32* inVec = in->data.C32;548 549 out = psVectorRecycle( out, PS_TYPE_F32, numElements );550 out->n = numElements;551 outVec = out->data.F32;552 553 for ( unsigned int i = 0;i < numElements;i++ ) {554 outVec[ i ] = crealf( inVec[ i ] );555 }556 } else {557 psError( __func__, "Can not extract real component from given vector type (%d).",558 type );559 psFree( out );560 return NULL;561 }562 551 psF32 * outVec; 552 psC32* inVec = in->data.C32; 553 554 out = psVectorRecycle( out, PS_TYPE_F32, numElements ); 555 out->n = numElements; 556 outVec = out->data.F32; 557 558 for ( unsigned int i = 0;i < numElements;i++ ) { 559 outVec[ i ] = crealf( inVec[ i ] ); 560 } 561 } else { 562 psError( __func__, "Can not extract real component from given vector type (%d).", 563 type ); 564 psFree( out ); 565 return NULL; 566 } 567 563 568 return out; 564 569 } … … 568 573 psElemType type; 569 574 unsigned int numElements; 570 571 572 if ( in == NULL ) { 573 psFree( out );574 return NULL;575 }576 575 576 577 if ( in == NULL ) { 578 psFree( out ); 579 return NULL; 580 } 581 577 582 type = in->type.type; 578 583 numElements = in->n; 579 584 580 585 /* if not a complex number, this is logically just zeroed image of same size */ 581 586 if ( ! PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 582 // Warn user, as this is probably not expected583 psLogMsg( __func__, PS_LOG_WARN, "Imaginary portion of a non-Complex type called for. "584 "A zeroed vector was returned." );585 out = psVectorRecycle( out, type, numElements );586 out->n = numElements;587 memset( out->data.V, 0, PSELEMTYPE_SIZEOF( type ) * numElements );588 return out;589 }590 587 // Warn user, as this is probably not expected 588 psLogMsg( __func__, PS_LOG_WARN, "Imaginary portion of a non-Complex type called for. " 589 "A zeroed vector was returned." ); 590 out = psVectorRecycle( out, type, numElements ); 591 out->n = numElements; 592 memset( out->data.V, 0, PSELEMTYPE_SIZEOF( type ) * numElements ); 593 return out; 594 } 595 591 596 if ( type == PS_TYPE_C32 ) { 592 psF32 * outVec;593 psC32* inVec = in->data.C32;594 595 out = psVectorRecycle( out, PS_TYPE_F32, numElements );596 out->n = numElements;597 outVec = out->data.F32;598 599 for ( unsigned int i = 0;i < numElements;i++ ) {600 outVec[ i ] = cimagf( inVec[ i ] );601 }602 } else {603 psError( __func__, "Can not extract imaginary component from given vector type (%d).",604 type );605 psFree( out );606 return NULL;607 }608 597 psF32 * outVec; 598 psC32* inVec = in->data.C32; 599 600 out = psVectorRecycle( out, PS_TYPE_F32, numElements ); 601 out->n = numElements; 602 outVec = out->data.F32; 603 604 for ( unsigned int i = 0;i < numElements;i++ ) { 605 outVec[ i ] = cimagf( inVec[ i ] ); 606 } 607 } else { 608 psError( __func__, "Can not extract imaginary component from given vector type (%d).", 609 type ); 610 psFree( out ); 611 return NULL; 612 } 613 609 614 return out; 610 615 } … … 614 619 psElemType type; 615 620 unsigned int numElements; 616 617 621 622 618 623 if ( real == NULL || imag == NULL ) { 619 psFree( out );620 return NULL;621 }622 624 psFree( out ); 625 return NULL; 626 } 627 623 628 type = real->type.type; 624 629 if ( real->n < imag->n ) { 625 numElements = real->n;626 } else {627 numElements = imag->n;628 }629 630 numElements = real->n; 631 } else { 632 numElements = imag->n; 633 } 634 630 635 if ( imag->type.type != type ) { 631 psError( __func__, "The inputs to psVectorComplex must be the same type." );632 psFree( out );633 return NULL;634 }635 636 psError( __func__, "The inputs to psVectorComplex must be the same type." ); 637 psFree( out ); 638 return NULL; 639 } 640 636 641 if ( PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 637 psError( __func__, "The inputs to psVectorComplex can not be complex." );638 psFree( out );639 return NULL;640 }641 642 psError( __func__, "The inputs to psVectorComplex can not be complex." ); 643 psFree( out ); 644 return NULL; 645 } 646 642 647 if ( type == PS_TYPE_F32 ) { 643 psC32 * outVec;644 psF32* realVec = real->data.F32;645 psF32* imagVec = imag->data.F32;646 647 out = psVectorRecycle( out, PS_TYPE_C32, numElements );648 out->n = numElements;649 outVec = out->data.C32;650 651 for ( unsigned int i = 0;i < numElements;i++ ) {652 outVec[ i ] = realVec[ i ] + I * imagVec[ i ];653 }654 } else {655 psError( __func__, "Can not merge real and imaginary portions for given vector type (%d).",656 type );657 psFree( out );658 return NULL;659 }660 648 psC32 * outVec; 649 psF32* realVec = real->data.F32; 650 psF32* imagVec = imag->data.F32; 651 652 out = psVectorRecycle( out, PS_TYPE_C32, numElements ); 653 out->n = numElements; 654 outVec = out->data.C32; 655 656 for ( unsigned int i = 0;i < numElements;i++ ) { 657 outVec[ i ] = realVec[ i ] + I * imagVec[ i ]; 658 } 659 } else { 660 psError( __func__, "Can not merge real and imaginary portions for given vector type (%d).", 661 type ); 662 psFree( out ); 663 return NULL; 664 } 665 661 666 return out; 662 667 } … … 666 671 psElemType type; 667 672 unsigned int numElements; 668 669 670 if ( in == NULL ) { 671 psFree( out );672 return NULL;673 }674 673 674 675 if ( in == NULL ) { 676 psFree( out ); 677 return NULL; 678 } 679 675 680 type = in->type.type; 676 681 numElements = in->n; 677 682 678 683 /* if not a complex number, this is logically just a image copy */ 679 684 if ( ! PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 680 // Warn user, as this is probably not expected681 psLogMsg( __func__, PS_LOG_WARN, "Complex Conjugate of a non-Complex type called for. "682 "Vector copy was performed instead." );683 684 out = psVectorRecycle( out, type, numElements );685 out->n = numElements;686 memcpy( out->data.V, in->data.V, PSELEMTYPE_SIZEOF( type ) * numElements );687 return out;688 }689 685 // Warn user, as this is probably not expected 686 psLogMsg( __func__, PS_LOG_WARN, "Complex Conjugate of a non-Complex type called for. " 687 "Vector copy was performed instead." ); 688 689 out = psVectorRecycle( out, type, numElements ); 690 out->n = numElements; 691 memcpy( out->data.V, in->data.V, PSELEMTYPE_SIZEOF( type ) * numElements ); 692 return out; 693 } 694 690 695 if ( type == PS_TYPE_C32 ) { 691 psC32 * outVec;692 psC32* inVec = in->data.C32;693 694 out = psVectorRecycle( out, PS_TYPE_C32, numElements );695 out->n = numElements;696 outVec = out->data.C32;697 698 for ( unsigned int i = 0;i < numElements;i++ ) {699 outVec[ i ] = crealf( inVec[ i ] ) - I * cimagf( inVec[ i ] );700 }701 } else {702 psError( __func__, "Can not compute complex conjugate for given vector type (%d).",703 type );704 psFree( out );705 return NULL;706 }707 696 psC32 * outVec; 697 psC32* inVec = in->data.C32; 698 699 out = psVectorRecycle( out, PS_TYPE_C32, numElements ); 700 out->n = numElements; 701 outVec = out->data.C32; 702 703 for ( unsigned int i = 0;i < numElements;i++ ) { 704 outVec[ i ] = crealf( inVec[ i ] ) - I * cimagf( inVec[ i ] ); 705 } 706 } else { 707 psError( __func__, "Can not compute complex conjugate for given vector type (%d).", 708 type ); 709 psFree( out ); 710 return NULL; 711 } 712 708 713 return out; 709 714 } … … 716 721 unsigned int inHalfNumElements; 717 722 unsigned int inNumElementsSquared; 718 719 if ( in == NULL ) { 720 psFree( out );721 return NULL;722 }723 723 724 if ( in == NULL ) { 725 psFree( out ); 726 return NULL; 727 } 728 724 729 type = in->type.type; 725 730 inNumElements = in->n; … … 727 732 inHalfNumElements = inNumElements / 2; 728 733 outNumElements = inHalfNumElements + 1; 729 734 730 735 /* if not a complex number, this is not implemented */ 731 736 if ( ! PS_IS_PSELEMTYPE_COMPLEX( type ) ) { 732 psError( __func__, "Power Spectrum for non-complex inputs is not implemented." );733 psFree( out );734 return NULL;735 }736 737 psError( __func__, "Power Spectrum for non-complex inputs is not implemented." ); 738 psFree( out ); 739 return NULL; 740 } 741 737 742 if ( type == PS_TYPE_C32 ) { 738 psF32 * outVec;739 psC32* inVec = in->data.C32;740 psF32 inAbs1;741 psF32 inAbs2;742 743 out = psVectorRecycle( out, PS_TYPE_F32, outNumElements );744 out->n = outNumElements;745 outVec = out->data.F32;746 747 // from ADD: P_0 = |C_0|^2/N^2748 inAbs1 = cabsf( inVec[ 0 ] );749 outVec[ 0 ] = inAbs1 * inAbs1 / inNumElementsSquared;750 751 // from ADD: P_j = (|C_j|^2+|C_N-j|^2)/N^2, where j = 1,2,...,(N/2-1)752 for ( unsigned int i = 1;i < inHalfNumElements;i++ ) {753 inAbs1 = cabsf( inVec[ i ] );754 inAbs2 = cabsf( inVec[ inNumElements - i ] );755 outVec[ i ] = ( inAbs1 * inAbs1 + inAbs2 * inAbs2 ) / inNumElementsSquared;756 }757 758 // from ADD: P_N/2 = |C_N/2|^2/N^2759 inAbs1 = cabsf( inVec[ inHalfNumElements ] );760 outVec[ inHalfNumElements ] = inAbs1 * inAbs1 / inNumElementsSquared;761 } else {762 psError( __func__, "Can not power spectrum for given vector type (%d).",763 type );764 psFree( out );765 return NULL;766 }767 768 return out; 769 770 } 743 psF32 * outVec; 744 psC32* inVec = in->data.C32; 745 psF32 inAbs1; 746 psF32 inAbs2; 747 748 out = psVectorRecycle( out, PS_TYPE_F32, outNumElements ); 749 out->n = outNumElements; 750 outVec = out->data.F32; 751 752 // from ADD: P_0 = |C_0|^2/N^2 753 inAbs1 = cabsf( inVec[ 0 ] ); 754 outVec[ 0 ] = inAbs1 * inAbs1 / inNumElementsSquared; 755 756 // from ADD: P_j = (|C_j|^2+|C_N-j|^2)/N^2, where j = 1,2,...,(N/2-1) 757 for ( unsigned int i = 1;i < inHalfNumElements;i++ ) { 758 inAbs1 = cabsf( inVec[ i ] ); 759 inAbs2 = cabsf( inVec[ inNumElements - i ] ); 760 outVec[ i ] = ( inAbs1 * inAbs1 + inAbs2 * inAbs2 ) / inNumElementsSquared; 761 } 762 763 // from ADD: P_N/2 = |C_N/2|^2/N^2 764 inAbs1 = cabsf( inVec[ inHalfNumElements ] ); 765 outVec[ inHalfNumElements ] = inAbs1 * inAbs1 / inNumElementsSquared; 766 } else { 767 psError( __func__, "Can not power spectrum for given vector type (%d).", 768 type ); 769 psFree( out ); 770 return NULL; 771 } 772 773 return out; 774 775 } -
trunk/psLib/src/fft/psVectorFFT.h
r974 r1385 7 7 * @author Robert DeSonia, MHPCC 8 8 * 9 * @version $Revision: 1. 6$ $Name: not supported by cvs2svn $10 * @date $Date: 2004-0 6-10 01:58:06$9 * @version $Revision: 1.7 $ $Name: not supported by cvs2svn $ 10 * @date $Date: 2004-08-04 23:37:39 $ 11 11 * 12 12 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/image/psImage.c
r1263 r1385 9 9 * @author Ross Harman, MHPCC 10 10 * 11 * @version $Revision: 1.3 5$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-0 7-22 20:42:22$11 * @version $Revision: 1.36 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-08-04 23:37:39 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/image/psImage.h
r1263 r1385 11 11 * @author Ross Harman, MHPCC 12 12 * 13 * @version $Revision: 1.2 5$ $Name: not supported by cvs2svn $14 * @date $Date: 2004-0 7-22 20:42:22$13 * @version $Revision: 1.26 $ $Name: not supported by cvs2svn $ 14 * @date $Date: 2004-08-04 23:37:39 $ 15 15 * 16 16 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/image/psImageExtraction.c
r1374 r1385 9 9 * @author Robert DeSonia, MHPCC 10 10 * 11 * @version $Revision: 1. 4$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-08-04 00:55:17$11 * @version $Revision: 1.5 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-08-04 23:37:39 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 29 29 unsigned int outputRowSize; // output row size in bytes 30 30 unsigned int inputColOffset; // offset in bytes to first subset pixel in input row 31 31 32 32 if ( image == NULL || image->data.V == NULL ) { 33 psError( __func__, "Can not subset image because input image or its pixel buffer is NULL." );34 return NULL;35 }36 33 psError( __func__, "Can not subset image because input image or its pixel buffer is NULL." ); 34 return NULL; 35 } 36 37 37 if ( image->type.dimen != PS_DIMEN_IMAGE ) { 38 psError( __func__, "Can not subset image because input image is not an image." );39 return NULL;40 }41 38 psError( __func__, "Can not subset image because input image is not an image." ); 39 return NULL; 40 } 41 42 42 if ( numCols < 1 || numRows < 1 ) { 43 psError( __func__, "Can not subset image because number of rows or columns are zero (%dx%d).",44 numCols, numRows );45 return NULL;46 }47 43 psError( __func__, "Can not subset image because number of rows or columns are zero (%dx%d).", 44 numCols, numRows ); 45 return NULL; 46 } 47 48 48 if ( col0 >= image->numCols || row0 >= image->numRows ) { 49 psError( __func__, "Can not subset image because col0,row0 (%d,%d) is not a valid pixel location.",50 col0, row0 );51 return NULL;52 }53 49 psError( __func__, "Can not subset image because col0,row0 (%d,%d) is not a valid pixel location.", 50 col0, row0 ); 51 return NULL; 52 } 53 54 54 /* validate subimage size */ 55 55 if ( col0 + numCols >= image->numCols || row0 + numRows >= image->numRows ) { 56 psError( __func__, "Can not subset image outside of image boundaries (size=%dx%d, "57 "subset=[%d:%d,%d:%d]).", image->numCols, image->numRows, col0,58 col0 + numCols, row0, row0 + numRows );59 return NULL;60 }61 62 56 psError( __func__, "Can not subset image outside of image boundaries (size=%dx%d, " 57 "subset=[%d:%d,%d:%d]).", image->numCols, image->numRows, col0, 58 col0 + numCols, row0, row0 + numRows ); 59 return NULL; 60 } 61 62 63 63 elementSize = PSELEMTYPE_SIZEOF( image->type.type ); 64 64 65 65 out = psImageRecycle( out, numCols, numRows, image->type.type ); 66 66 67 67 // set the parent information into the child output image 68 68 *( int* ) & out->row0 = row0; 69 69 *( int* ) & out->col0 = col0; 70 70 *( psImage** ) & out->parent = ( psImage* ) image; 71 71 72 72 // add output image as a child of the input image. 73 73 image->nChildren++; … … 75 75 image->nChildren * sizeof( psImage* ) ); 76 76 image->children[ image->nChildren - 1 ] = out; 77 77 78 78 inputColOffset = elementSize * col0; 79 79 outputRowSize = elementSize * numCols; 80 80 81 81 for ( int row = 0; row < numRows; row++ ) { 82 memcpy( out->data.V[ row ], image->data.U8[ row0 + row ] + inputColOffset,83 outputRowSize );84 }85 82 memcpy( out->data.V[ row ], image->data.U8[ row0 + row ] + inputColOffset, 83 outputRowSize ); 84 } 85 86 86 return ( out ); 87 87 } … … 96 96 int numRows; 97 97 int numCols; 98 98 99 99 if ( input == NULL || input->data.V == NULL ) { 100 psError( __func__, "Can not copy image because input image or its pixel buffer is NULL." );101 psFree( output );102 return NULL;103 }104 100 psError( __func__, "Can not copy image because input image or its pixel buffer is NULL." ); 101 psFree( output ); 102 return NULL; 103 } 104 105 105 if ( input == output ) { 106 psError( __func__, "Can not copy image because given input and output "107 "parameter reference the same psImage struct." );108 psFree( output );109 return NULL;110 }111 106 psError( __func__, "Can not copy image because given input and output " 107 "parameter reference the same psImage struct." ); 108 psFree( output ); 109 return NULL; 110 } 111 112 112 if ( input->type.dimen != PS_DIMEN_IMAGE ) { 113 psError( __func__, "Can not copy image because input image is not actually an image." );114 psFree( output );115 return NULL;116 }117 113 psError( __func__, "Can not copy image because input image is not actually an image." ); 114 psFree( output ); 115 return NULL; 116 } 117 118 118 inDatatype = input->type.type; 119 119 numRows = input->numRows; … … 121 121 elements = numRows * numCols; 122 122 elementSize = PSELEMTYPE_SIZEOF( inDatatype ); 123 123 124 124 if ( inDatatype == PS_TYPE_PTR || type == PS_TYPE_PTR ) { 125 psError( __func__, "Can not copy image to/from a void* matrix" );126 psFree( output );127 return NULL;128 }129 125 psError( __func__, "Can not copy image to/from a void* matrix" ); 126 psFree( output ); 127 return NULL; 128 } 129 130 130 output = psImageRecycle( output, numCols, numRows, type ); 131 131 132 132 // cover the trival case of copy of the same datatype. 133 133 if ( type == inDatatype ) { 134 memcpy( output->data.V[ 0 ], input->data.V[ 0 ], elementSize * elements );135 return output;136 }137 134 memcpy( output->data.V[ 0 ], input->data.V[ 0 ], elementSize * elements ); 135 return output; 136 } 137 138 138 #define PSIMAGE_ELEMENT_COPY(IN,INTYPE,OUT,OUTTYPE,ELEMENTS) { \ 139 139 ps##INTYPE *in = IN->data.INTYPE[0]; \ 140 140 ps##OUTTYPE *out = OUT->data.OUTTYPE[0]; \ 141 141 for (int e=0;e<ELEMENTS;e++) { \ 142 *(out++) = *(in++); \143 } \144 } 145 142 *(out++) = *(in++); \ 143 } \ 144 } 145 146 146 #define PSIMAGE_COPY_CASE(OUT,OUTTYPE) \ 147 147 switch (inDatatype) { \ 148 case PS_TYPE_S8: \149 PSIMAGE_ELEMENT_COPY(input,S8,OUT,OUTTYPE,elements); \150 break; \151 case PS_TYPE_S16: \152 PSIMAGE_ELEMENT_COPY(input,S16,OUT,OUTTYPE,elements); \153 break; \154 case PS_TYPE_S32: \155 PSIMAGE_ELEMENT_COPY(input,S32,OUT,OUTTYPE,elements); \156 break; \157 case PS_TYPE_S64: \158 PSIMAGE_ELEMENT_COPY(input,S64,OUT,OUTTYPE,elements); \159 break; \160 case PS_TYPE_U8: \161 PSIMAGE_ELEMENT_COPY(input,U8,OUT,OUTTYPE,elements); \162 break; \163 case PS_TYPE_U16: \164 PSIMAGE_ELEMENT_COPY(input,U16,OUT,OUTTYPE,elements); \165 break; \166 case PS_TYPE_U32: \167 PSIMAGE_ELEMENT_COPY(input,U32,OUT,OUTTYPE,elements); \168 break; \169 case PS_TYPE_U64: \170 PSIMAGE_ELEMENT_COPY(input,U64,OUT,OUTTYPE,elements); \171 break; \172 case PS_TYPE_F32: \173 PSIMAGE_ELEMENT_COPY(input,F32,OUT,OUTTYPE,elements); \174 break; \175 case PS_TYPE_F64: \176 PSIMAGE_ELEMENT_COPY(input,F64,OUT,OUTTYPE,elements); \177 break; \178 case PS_TYPE_C32: \179 PSIMAGE_ELEMENT_COPY(input,C32,OUT,OUTTYPE,elements); \180 break; \181 case PS_TYPE_C64: \182 PSIMAGE_ELEMENT_COPY(input,C64,OUT,OUTTYPE,elements); \183 break; \184 default: \185 break; \186 }187 148 case PS_TYPE_S8: \ 149 PSIMAGE_ELEMENT_COPY(input,S8,OUT,OUTTYPE,elements); \ 150 break; \ 151 case PS_TYPE_S16: \ 152 PSIMAGE_ELEMENT_COPY(input,S16,OUT,OUTTYPE,elements); \ 153 break; \ 154 case PS_TYPE_S32: \ 155 PSIMAGE_ELEMENT_COPY(input,S32,OUT,OUTTYPE,elements); \ 156 break; \ 157 case PS_TYPE_S64: \ 158 PSIMAGE_ELEMENT_COPY(input,S64,OUT,OUTTYPE,elements); \ 159 break; \ 160 case PS_TYPE_U8: \ 161 PSIMAGE_ELEMENT_COPY(input,U8,OUT,OUTTYPE,elements); \ 162 break; \ 163 case PS_TYPE_U16: \ 164 PSIMAGE_ELEMENT_COPY(input,U16,OUT,OUTTYPE,elements); \ 165 break; \ 166 case PS_TYPE_U32: \ 167 PSIMAGE_ELEMENT_COPY(input,U32,OUT,OUTTYPE,elements); \ 168 break; \ 169 case PS_TYPE_U64: \ 170 PSIMAGE_ELEMENT_COPY(input,U64,OUT,OUTTYPE,elements); \ 171 break; \ 172 case PS_TYPE_F32: \ 173 PSIMAGE_ELEMENT_COPY(input,F32,OUT,OUTTYPE,elements); \ 174 break; \ 175 case PS_TYPE_F64: \ 176 PSIMAGE_ELEMENT_COPY(input,F64,OUT,OUTTYPE,elements); \ 177 break; \ 178 case PS_TYPE_C32: \ 179 PSIMAGE_ELEMENT_COPY(input,C32,OUT,OUTTYPE,elements); \ 180 break; \ 181 case PS_TYPE_C64: \ 182 PSIMAGE_ELEMENT_COPY(input,C64,OUT,OUTTYPE,elements); \ 183 break; \ 184 default: \ 185 break; \ 186 } 187 188 188 switch ( type ) { 189 case PS_TYPE_S8:190 PSIMAGE_COPY_CASE( output, S8 );191 break;192 case PS_TYPE_S16:193 PSIMAGE_COPY_CASE( output, S16 );194 break;195 case PS_TYPE_S32:196 PSIMAGE_COPY_CASE( output, S32 );197 break;198 case PS_TYPE_S64:199 PSIMAGE_COPY_CASE( output, S64 );200 break;201 case PS_TYPE_U8:202 PSIMAGE_COPY_CASE( output, U8 );203 break;204 case PS_TYPE_U16:205 PSIMAGE_COPY_CASE( output, U16 );206 break;207 case PS_TYPE_U32:208 PSIMAGE_COPY_CASE( output, U32 );209 break;210 case PS_TYPE_U64:211 PSIMAGE_COPY_CASE( output, U64 );212 break;213 case PS_TYPE_F32:214 PSIMAGE_COPY_CASE( output, F32 );215 break;216 case PS_TYPE_F64:217 PSIMAGE_COPY_CASE( output, F64 );218 break;219 case PS_TYPE_C32:220 PSIMAGE_COPY_CASE( output, C32 );221 break;222 case PS_TYPE_C64:223 PSIMAGE_COPY_CASE( output, C64 );224 break;225 default:226 break;227 }189 case PS_TYPE_S8: 190 PSIMAGE_COPY_CASE( output, S8 ); 191 break; 192 case PS_TYPE_S16: 193 PSIMAGE_COPY_CASE( output, S16 ); 194 break; 195 case PS_TYPE_S32: 196 PSIMAGE_COPY_CASE( output, S32 ); 197 break; 198 case PS_TYPE_S64: 199 PSIMAGE_COPY_CASE( output, S64 ); 200 break; 201 case PS_TYPE_U8: 202 PSIMAGE_COPY_CASE( output, U8 ); 203 break; 204 case PS_TYPE_U16: 205 PSIMAGE_COPY_CASE( output, U16 ); 206 break; 207 case PS_TYPE_U32: 208 PSIMAGE_COPY_CASE( output, U32 ); 209 break; 210 case PS_TYPE_U64: 211 PSIMAGE_COPY_CASE( output, U64 ); 212 break; 213 case PS_TYPE_F32: 214 PSIMAGE_COPY_CASE( output, F32 ); 215 break; 216 case PS_TYPE_F64: 217 PSIMAGE_COPY_CASE( output, F64 ); 218 break; 219 case PS_TYPE_C32: 220 PSIMAGE_COPY_CASE( output, C32 ); 221 break; 222 case PS_TYPE_C64: 223 PSIMAGE_COPY_CASE( output, C64 ); 224 break; 225 default: 226 break; 227 } 228 228 return output; 229 229 } … … 247 247 int delta = 1; 248 248 psF64* outData; 249 249 250 250 if ( in == NULL || in->data.V == NULL ) { 251 psError( __func__, "Input image can not be NULL." );252 psFree( out );253 return NULL;254 }255 251 psError( __func__, "Input image can not be NULL." ); 252 psFree( out ); 253 return NULL; 254 } 255 256 256 if ( numRows == 0 || numCols == 0 ) { 257 psError( __func__, "The specified region contains no data (%dx%d)",258 numCols, numRows );259 psFree( out );260 return NULL;261 }262 257 psError( __func__, "The specified region contains no data (%dx%d)", 258 numCols, numRows ); 259 psFree( out ); 260 return NULL; 261 } 262 263 263 type = in->type.type; 264 264 inRows = in->numRows; 265 265 inCols = in->numCols; 266 266 267 267 if ( direction == PS_CUT_X_NEG || direction == PS_CUT_Y_NEG ) { 268 delta = -1;269 }270 268 delta = -1; 269 } 270 271 271 // if numRows/numCols is negative, invert the problem to give positive 272 272 // numRows/numCols (and cut in opposite direction). 273 273 if ( numRows < 0 ) { 274 numRows = -numRows;275 row -= ( numRows - 1 );276 delta = -delta;277 }278 274 numRows = -numRows; 275 row -= ( numRows - 1 ); 276 delta = -delta; 277 } 278 279 279 if ( numCols < 0 ) { 280 numCols = -numCols;281 col -= ( numCols - 1 );282 delta = -delta;283 }284 280 numCols = -numCols; 281 col -= ( numCols - 1 ); 282 delta = -delta; 283 } 284 285 285 if ( mask != NULL ) { 286 if ( inRows != mask->numRows || inCols != mask->numCols ) {287 psError( __func__, "The mask and image dimensions did not match (%dx%d vs %dx%d)",288 mask->numCols, mask->numRows, in->numCols, in->numRows );289 psFree( out );290 }291 if ( mask->type.type != PS_TYPE_MASK ) {292 psError( __func__, "The mask datatype (%d) must be %s.",293 mask->type.type, PS_TYPE_MASK_NAME );294 psFree( out );295 }296 }297 286 if ( inRows != mask->numRows || inCols != mask->numCols ) { 287 psError( __func__, "The mask and image dimensions did not match (%dx%d vs %dx%d)", 288 mask->numCols, mask->numRows, in->numCols, in->numRows ); 289 psFree( out ); 290 } 291 if ( mask->type.type != PS_TYPE_MASK ) { 292 psError( __func__, "The mask datatype (%d) must be %s.", 293 mask->type.type, PS_TYPE_MASK_NAME ); 294 psFree( out ); 295 } 296 } 297 298 298 if ( row >= inRows || col >= inCols || 299 299 col + numCols > in->numCols || row + numRows > in->numRows ) { 300 psError( __func__, "The specified image region (%d,%d to %d,%d) is outside of image area (0,0 to %d,%d).",301 col, row, col + numCols - 1, row + numRows - 1, in->numCols - 1, in->numRows - 1 );302 psFree( out );303 return NULL;304 }305 300 psError( __func__, "The specified image region (%d,%d to %d,%d) is outside of image area (0,0 to %d,%d).", 301 col, row, col + numCols - 1, row + numRows - 1, in->numCols - 1, in->numRows - 1 ); 302 psFree( out ); 303 return NULL; 304 } 305 306 306 // verify that the stats struct specifies a single stats operation 307 307 if ( stats == NULL || p_psGetStatValue( stats, &statVal ) == false ) { 308 psError( __func__, "The stat options didn't specify a single supported statistic type." );309 psFree( out );310 return NULL;311 }312 308 psError( __func__, "The stat options didn't specify a single supported statistic type." ); 309 psFree( out ); 310 return NULL; 311 } 312 313 313 // since stats input is const, I need to create a 'scratch' stats struct 314 314 myStats = psAlloc( sizeof( psStats ) ); 315 315 *myStats = *stats; 316 317 318 316 317 318 319 319 if ( direction == PS_CUT_X_POS || direction == PS_CUT_X_NEG ) { 320 psVector * imgVec = psVectorAlloc( numRows, type ); 321 psVector* maskVec = NULL; 322 psMaskType* maskData = NULL; 323 324 // recycle output to make a proper sized/type output structure 325 // n.b. type is double as that is the type given for all stats in psStats. 326 out = psVectorRecycle( out, PS_TYPE_F64, numCols ); 327 outData = out->data.F64; 328 if ( delta < 0 ) { 329 outData += numCols - 1; 330 } 331 332 if ( mask != NULL ) { 333 maskVec = psVectorAlloc( numRows, mask->type.type ); 334 } 335 336 #define PSIMAGE_CUT_VERTICAL(TYPE) \ 337 case PS_TYPE_##TYPE: { \ 338 psMaskType* maskVecData = NULL; \ 339 for (int c=0;c<numCols;c++) { \ 340 ps##TYPE *imgData = in->data.TYPE[row] + col + c; \ 341 ps##TYPE *imgVecData = imgVec->data.TYPE; \ 342 if (maskVec != NULL) { \ 343 maskVecData = maskVec->data.V; \ 344 maskData = (psMaskType*)(mask->data.V[row]) + col + c; \ 345 } \ 346 for (int r=0;r<numRows;r++) { \ 347 *(imgVecData++) = *imgData; \ 348 imgData += inCols; \ 349 if (maskVecData != NULL) { \ 350 *(maskVecData++) = *maskData; \ 351 maskData += inCols; \ 352 } \ 353 } \ 354 myStats = psVectorStats(myStats,imgVec,maskVec,maskVal); \ 355 (void)p_psGetStatValue(myStats,&statVal); \ 356 *outData = statVal; \ 357 outData += delta; \ 320 psVector * imgVec = psVectorAlloc( numRows, type ); 321 psVector* maskVec = NULL; 322 psMaskType* maskData = NULL; 323 324 // recycle output to make a proper sized/type output structure 325 // n.b. type is double as that is the type given for all stats in psStats. 326 out = psVectorRecycle( out, PS_TYPE_F64, numCols ); 327 outData = out->data.F64; 328 if ( delta < 0 ) { 329 outData += numCols - 1; 330 } 331 332 if ( mask != NULL ) { 333 maskVec = psVectorAlloc( numRows, mask->type.type ); 334 } 335 336 #define PSIMAGE_CUT_VERTICAL(TYPE) \ 337 case PS_TYPE_##TYPE: { \ 338 psMaskType* maskVecData = NULL; \ 339 for (int c=0;c<numCols;c++) { \ 340 ps##TYPE *imgData = in->data.TYPE[row] + col + c; \ 341 ps##TYPE *imgVecData = imgVec->data.TYPE; \ 342 if (maskVec != NULL) { \ 343 maskVecData = maskVec->data.V; \ 344 maskData = (psMaskType*)(mask->data.V[row]) + col + c; \ 345 } \ 346 for (int r=0;r<numRows;r++) { \ 347 *(imgVecData++) = *imgData; \ 348 imgData += inCols; \ 349 if (maskVecData != NULL) { \ 350 *(maskVecData++) = *maskData; \ 351 maskData += inCols; \ 358 352 } \ 359 break; \ 360 } 361 362 switch ( type ) { 363 PSIMAGE_CUT_VERTICAL( U8 ); 364 PSIMAGE_CUT_VERTICAL( U16 ); 365 PSIMAGE_CUT_VERTICAL( U32 ); 366 PSIMAGE_CUT_VERTICAL( U64 ); 367 PSIMAGE_CUT_VERTICAL( S8 ); 368 PSIMAGE_CUT_VERTICAL( S16 ); 369 PSIMAGE_CUT_VERTICAL( S32 ); 370 PSIMAGE_CUT_VERTICAL( S64 ); 371 PSIMAGE_CUT_VERTICAL( F32 ); 372 PSIMAGE_CUT_VERTICAL( F64 ); 373 PSIMAGE_CUT_VERTICAL( C32 ); 374 PSIMAGE_CUT_VERTICAL( C64 ); 375 default: 376 psError( __func__, "Unsupported datatype (%d)", type ); 377 psFree( out ); 378 out = NULL; 379 } 380 psFree( imgVec ); 381 psFree( maskVec ); 382 } else if ( direction == PS_CUT_Y_POS || direction == PS_CUT_Y_NEG ) { // Cut in Y direction 353 } \ 354 myStats = psVectorStats(myStats,imgVec,maskVec,maskVal); \ 355 (void)p_psGetStatValue(myStats,&statVal); \ 356 *outData = statVal; \ 357 outData += delta; \ 358 } \ 359 break; \ 360 } 361 362 switch ( type ) { 363 PSIMAGE_CUT_VERTICAL( U8 ); 364 PSIMAGE_CUT_VERTICAL( U16 ); 365 PSIMAGE_CUT_VERTICAL( U32 ); 366 PSIMAGE_CUT_VERTICAL( U64 ); 367 PSIMAGE_CUT_VERTICAL( S8 ); 368 PSIMAGE_CUT_VERTICAL( S16 ); 369 PSIMAGE_CUT_VERTICAL( S32 ); 370 PSIMAGE_CUT_VERTICAL( S64 ); 371 PSIMAGE_CUT_VERTICAL( F32 ); 372 PSIMAGE_CUT_VERTICAL( F64 ); 373 PSIMAGE_CUT_VERTICAL( C32 ); 374 PSIMAGE_CUT_VERTICAL( C64 ); 375 default: 376 psError( __func__, "Unsupported datatype (%d)", type ); 377 psFree( out ); 378 out = NULL; 379 } 380 psFree( imgVec ); 381 psFree( maskVec ); 382 } else 383 if ( direction == PS_CUT_Y_POS || direction == PS_CUT_Y_NEG ) { // Cut in Y direction 383 384 psVector * imgVec = NULL; 384 385 psVector* maskVec = NULL; 385 386 int elementSize = PSELEMTYPE_SIZEOF( type ); 386 387 387 388 // fill in psVectors to fake out the statistics functions. 388 389 imgVec = psAlloc( sizeof( psVector ) ); … … 390 391 imgVec->n = imgVec->nalloc = numCols; 391 392 if ( mask != NULL ) { 392 maskVec = psAlloc( sizeof( psVector ) );393 maskVec->type = mask->type;394 maskVec->n = maskVec->nalloc = numCols;395 }396 393 maskVec = psAlloc( sizeof( psVector ) ); 394 maskVec->type = mask->type; 395 maskVec->n = maskVec->nalloc = numCols; 396 } 397 397 398 // recycle output to make a proper sized/type output structure 398 399 // n.b. type is double as that is the type given for all stats in psStats. … … 400 401 outData = out->data.F64; 401 402 if ( delta < 0 ) { 402 outData += numRows - 1; 403 outData += numRows - 1; 404 } 405 406 for ( int r = 0;r < numRows;r++ ) { 407 // point the vector struct to the data to calculate the stats 408 imgVec->data.V = ( void* ) ( in->data.U8[ row + r ] + col * elementSize ); 409 if ( maskVec != NULL ) { 410 maskVec->data.V = ( void* ) ( mask->data.U8[ row + r ] + col * sizeof( psMaskType ) ); 403 411 } 404 405 for ( int r = 0;r < numRows;r++ ) { 406 // point the vector struct to the data to calculate the stats 407 imgVec->data.V = ( void* ) ( in->data.U8[ row + r ] + col * elementSize ); 408 if ( maskVec != NULL ) { 409 maskVec->data.V = ( void* ) ( mask->data.U8[ row + r ] + col * sizeof( psMaskType ) ); 410 } 411 myStats = psVectorStats( myStats, imgVec, maskVec, maskVal ); 412 ( void ) p_psGetStatValue( myStats, &statVal ); // we know it works cause we tested it above 413 *outData = statVal; 414 outData += delta; 415 } 412 myStats = psVectorStats( myStats, imgVec, maskVec, maskVal ); 413 ( void ) p_psGetStatValue( myStats, &statVal ); // we know it works cause we tested it above 414 *outData = statVal; 415 outData += delta; 416 } 416 417 psFree( imgVec ); 417 418 psFree( maskVec ); … … 421 422 out = NULL; 422 423 } 423 424 424 425 psFree( myStats ); 425 426 426 427 return out; 427 428 } -
trunk/psLib/src/image/psImageIO.c
r1301 r1385 7 7 * @author Robert DeSonia, MHPCC 8 8 * 9 * @version $Revision: 1. 6$ $Name: not supported by cvs2svn $10 * @date $Date: 2004-0 7-27 23:09:23$9 * @version $Revision: 1.7 $ $Name: not supported by cvs2svn $ 10 * @date $Date: 2004-08-04 23:37:39 $ 11 11 * 12 12 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 303 303 extnum, numHDUs); 304 304 return false; 305 } else if (numHDUs == extnum) { 306 createNewHDU = true; 307 } else if (fits_movabs_hdu(fptr, extnum+1, &hduType, &status) != 0) { 308 fits_get_errstatus(status, fitsErr); 309 status = 0; 310 (void)fits_close_file(fptr, &status); 311 psError(__func__,"Could not index to HDU #%d for file %s. (%s)", 312 extnum, filename, fitsErr); 313 return false; 314 } 305 } else 306 if (numHDUs == extnum) { 307 createNewHDU = true; 308 } else 309 if (fits_movabs_hdu(fptr, extnum+1, &hduType, &status) != 0) { 310 fits_get_errstatus(status, fitsErr); 311 status = 0; 312 (void)fits_close_file(fptr, &status); 313 psError(__func__,"Could not index to HDU #%d for file %s. (%s)", 314 extnum, filename, fitsErr); 315 return false; 316 } 315 317 } 316 318 -
trunk/psLib/src/image/psImageManip.c
r1319 r1385 10 10 * @author Ross Harman, MHPCC 11 11 * 12 * @version $Revision: 1. 8$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-0 7-29 01:20:10$12 * @version $Revision: 1.9 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2004-08-04 23:37:39 $ 14 14 * 15 15 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 582 582 return NULL; 583 583 } 584 } else if (fabsf(angle-180.0f) < FLT_EPSILON) { 585 // perform 1/2 rotate 586 int numRows = in->numRows; 587 int lastRow = numRows - 1; 588 int numCols = in->numCols; 589 int lastCol = numCols - 1; 590 psElemType type = in->type.type; 591 out = psImageRecycle(out,numCols,numRows,type); 592 593 #define PSIMAGE_ROTATE_180_CASE(TYPE) \ 594 case PS_TYPE_##TYPE: { \ 595 for (int row=0;row<numRows;row++) { \ 596 ps##TYPE* outRow = out->data.TYPE[row]; \ 597 ps##TYPE* inRow = in->data.TYPE[lastRow-row]; \ 598 for (int col=0;col<numCols;col++) { \ 599 outRow[col] = inRow[lastCol - col]; \ 584 } else 585 if (fabsf(angle-180.0f) < FLT_EPSILON) { 586 // perform 1/2 rotate 587 int numRows = in->numRows; 588 int lastRow = numRows - 1; 589 int numCols = in->numCols; 590 int lastCol = numCols - 1; 591 psElemType type = in->type.type; 592 out = psImageRecycle(out,numCols,numRows,type); 593 594 #define PSIMAGE_ROTATE_180_CASE(TYPE) \ 595 case PS_TYPE_##TYPE: { \ 596 for (int row=0;row<numRows;row++) { \ 597 ps##TYPE* outRow = out->data.TYPE[row]; \ 598 ps##TYPE* inRow = in->data.TYPE[lastRow-row]; \ 599 for (int col=0;col<numCols;col++) { \ 600 outRow[col] = inRow[lastCol - col]; \ 601 } \ 600 602 } \ 601 603 } \ 602 } \ 603 break; 604 605 switch (type) { 606 PSIMAGE_ROTATE_180_CASE(U8); 607 PSIMAGE_ROTATE_180_CASE(U16); 608 PSIMAGE_ROTATE_180_CASE(U32); 609 PSIMAGE_ROTATE_180_CASE(U64); 610 PSIMAGE_ROTATE_180_CASE(S8); 611 PSIMAGE_ROTATE_180_CASE(S16); 612 PSIMAGE_ROTATE_180_CASE(S32); 613 PSIMAGE_ROTATE_180_CASE(S64); 614 PSIMAGE_ROTATE_180_CASE(F32); 615 PSIMAGE_ROTATE_180_CASE(F64); 616 PSIMAGE_ROTATE_180_CASE(C32); 617 PSIMAGE_ROTATE_180_CASE(C64); 618 default: 619 psError(__func__,"Unsupported type (%d)",type); 620 psFree(out); 621 return NULL; 622 } 623 } else if (fabsf(angle-270.0f) < FLT_EPSILON) { 624 // perform 1/4 rotate clockwise 625 int numRows = in->numCols; 626 int lastRow = numRows - 1; 627 int numCols = in->numRows; 628 psElemType type = in->type.type; 629 out = psImageRecycle(out,numCols,numRows,type); 630 631 #define PSIMAGE_ROTATE_RIGHT_90(TYPE) \ 632 case PS_TYPE_##TYPE: { \ 633 ps##TYPE** inData = in->data.TYPE; \ 634 for (int row=0;row<numRows;row++) { \ 635 ps##TYPE* outRow = out->data.TYPE[row]; \ 636 for (int col=0;col<numCols;col++) { \ 637 outRow[col] = inData[col][lastRow-row]; \ 604 break; 605 606 switch (type) { 607 PSIMAGE_ROTATE_180_CASE(U8); 608 PSIMAGE_ROTATE_180_CASE(U16); 609 PSIMAGE_ROTATE_180_CASE(U32); 610 PSIMAGE_ROTATE_180_CASE(U64); 611 PSIMAGE_ROTATE_180_CASE(S8); 612 PSIMAGE_ROTATE_180_CASE(S16); 613 PSIMAGE_ROTATE_180_CASE(S32); 614 PSIMAGE_ROTATE_180_CASE(S64); 615 PSIMAGE_ROTATE_180_CASE(F32); 616 PSIMAGE_ROTATE_180_CASE(F64); 617 PSIMAGE_ROTATE_180_CASE(C32); 618 PSIMAGE_ROTATE_180_CASE(C64); 619 default: 620 psError(__func__,"Unsupported type (%d)",type); 621 psFree(out); 622 return NULL; 623 } 624 } else 625 if (fabsf(angle-270.0f) < FLT_EPSILON) { 626 // perform 1/4 rotate clockwise 627 int numRows = in->numCols; 628 int lastRow = numRows - 1; 629 int numCols = in->numRows; 630 psElemType type = in->type.type; 631 out = psImageRecycle(out,numCols,numRows,type); 632 633 #define PSIMAGE_ROTATE_RIGHT_90(TYPE) \ 634 case PS_TYPE_##TYPE: { \ 635 ps##TYPE** inData = in->data.TYPE; \ 636 for (int row=0;row<numRows;row++) { \ 637 ps##TYPE* outRow = out->data.TYPE[row]; \ 638 for (int col=0;col<numCols;col++) { \ 639 outRow[col] = inData[col][lastRow-row]; \ 640 } \ 641 } \ 638 642 } \ 639 } \ 640 } \ 641 break; 642 643 switch (type) { 644 PSIMAGE_ROTATE_RIGHT_90(U8); 645 PSIMAGE_ROTATE_RIGHT_90(U16); 646 PSIMAGE_ROTATE_RIGHT_90(U32); 647 PSIMAGE_ROTATE_RIGHT_90(U64); 648 PSIMAGE_ROTATE_RIGHT_90(S8); 649 PSIMAGE_ROTATE_RIGHT_90(S16); 650 PSIMAGE_ROTATE_RIGHT_90(S32); 651 PSIMAGE_ROTATE_RIGHT_90(S64); 652 PSIMAGE_ROTATE_RIGHT_90(F32); 653 PSIMAGE_ROTATE_RIGHT_90(F64); 654 PSIMAGE_ROTATE_RIGHT_90(C32); 655 PSIMAGE_ROTATE_RIGHT_90(C64); 656 default: 657 psError(__func__,"Unsupported type (%d)",type); 658 psFree(out); 659 return NULL; 660 } 661 } else if (fabsf(angle) < FLT_EPSILON) { 662 out = psImageCopy(out,in,in->type.type); 663 } else { 664 psElemType type = in->type.type; 665 int numRows = in->numRows; 666 int numCols = in->numCols; 667 double centerX = (float)(numCols) / 2.0f; 668 float centerY = (float)(numRows) / 2.0f; 669 float t = angle*(3.14159265358f/180.0f); 670 float cosT = cosf(t); 671 float sinT = sinf(t); 672 673 // calculate the corners of the rotated image so we know the proper output image size. 674 // x' = x cos(t) + y sin(t); i.e, x' = (x-centerX)*cosT + (y-centerY)*sinT; 675 // y' = y cos(t) - x sin(t); i.e. y' = (y-centerY)*cosT - (x-centerX)*sinT; 676 677 678 int outCols = ceil(abs(numCols*cosT)+abs(numRows*sinT))+1; 679 int outRows = ceil(abs(numCols*sinT)+abs(numRows*cosT))+1; 680 float minX = (float)outCols/-2.0f; 681 int intMinY = outRows/-2; 682 683 out = psImageRecycle(out,outCols,outRows,type); 684 685 /* optimized public domain rotation routine by Karl Lager 686 float cosT,sinT; 687 cosT = cos(t); 688 sinT = sin(t); 689 for (y = min_y; y <= max_y; y++) 690 { x' = min_x * cosT + y * sinT + x1'; 691 y' = y * cosT - min_x * sinT + y1'; 692 for (x = min_x; x <= max_x; x++) 693 { if (x', y') is in the bounds of the bitmap, 694 get pixel(x', y') and plot the pixel to 695 (x, y) on screen. 696 x' += cosT; 697 y' -= sinT; 698 } 699 } 700 */ 701 702 // precalculate some figures that are used within loop 703 float minXTimesCosTPlusCenterX = minX*cosT+centerX; 704 float CenterYMinusminXTimesSinT = centerY-minX*sinT; 705 706 #define PSIMAGE_ROTATE_ARBITRARY_LOOP(TYPE,MODE) { \ 707 if (unexposedValue < PS_MIN_##TYPE || unexposedValue > PS_MAX_##TYPE) { \ 708 psError(__func__,"The given unexposedValue (%g) is outside of the " \ 709 "image type's range (%g->%g).", \ 710 unexposedValue, (double)PS_MIN_##TYPE,(double)PS_MAX_##TYPE); \ 711 psFree(out); \ 712 out = NULL; \ 713 break; \ 714 } \ 715 float inX; \ 716 float inY; \ 717 ps##TYPE* outRow; \ 718 for (int y = 0; y < outRows; y++) { \ 719 inX = minXTimesCosTPlusCenterX + (y+intMinY) * sinT; \ 720 inY = CenterYMinusminXTimesSinT + (y+intMinY) * cosT; \ 721 outRow = out->data.TYPE[y]; \ 722 for (int x = 0; x < outCols; x++) { \ 723 outRow[x] = p_psImagePixelInterpolate##MODE##_##TYPE(in,inX,inY,unexposedValue); \ 724 inX += cosT; \ 725 inY -= sinT; \ 726 } \ 727 } \ 728 } 729 730 #define PSIMAGE_ROTATE_ARBITRARY_CASE(MODE) \ 731 case PS_INTERPOLATE_##MODE: \ 732 switch (type) { \ 733 case PS_TYPE_U8: \ 734 PSIMAGE_ROTATE_ARBITRARY_LOOP(U8,MODE); \ 735 break; \ 736 case PS_TYPE_U16: \ 737 PSIMAGE_ROTATE_ARBITRARY_LOOP(U16,MODE); \ 738 break; \ 739 case PS_TYPE_U32: \ 740 PSIMAGE_ROTATE_ARBITRARY_LOOP(U32,MODE); \ 741 break; \ 742 case PS_TYPE_U64: \ 743 PSIMAGE_ROTATE_ARBITRARY_LOOP(U64,MODE); \ 744 break; \ 745 case PS_TYPE_S8: \ 746 PSIMAGE_ROTATE_ARBITRARY_LOOP(S8,MODE); \ 747 break; \ 748 case PS_TYPE_S16: \ 749 PSIMAGE_ROTATE_ARBITRARY_LOOP(S16,MODE); \ 750 break; \ 751 case PS_TYPE_S32: \ 752 PSIMAGE_ROTATE_ARBITRARY_LOOP(S32,MODE); \ 753 break; \ 754 case PS_TYPE_S64: \ 755 PSIMAGE_ROTATE_ARBITRARY_LOOP(S64,MODE); \ 756 break; \ 757 case PS_TYPE_F32: \ 758 PSIMAGE_ROTATE_ARBITRARY_LOOP(F32,MODE); \ 759 break; \ 760 case PS_TYPE_F64: \ 761 PSIMAGE_ROTATE_ARBITRARY_LOOP(F64,MODE); \ 762 break; \ 763 case PS_TYPE_C32: \ 764 PSIMAGE_ROTATE_ARBITRARY_LOOP(C32,MODE); \ 765 break; \ 766 case PS_TYPE_C64: \ 767 PSIMAGE_ROTATE_ARBITRARY_LOOP(C64,MODE); \ 768 break; \ 769 default: \ 770 psError(__func__,"Image type (%d) not supported",type); \ 771 psFree(out); \ 772 out = NULL; \ 773 } \ 774 break; 775 776 switch (mode) { 777 PSIMAGE_ROTATE_ARBITRARY_CASE(FLAT); 778 PSIMAGE_ROTATE_ARBITRARY_CASE(BILINEAR); 779 default: 780 psError(__func__,"Unsupported interpolation mode (%d)",mode); 781 psFree(out); 782 out = NULL; 783 } 784 } 643 break; 644 645 switch (type) { 646 PSIMAGE_ROTATE_RIGHT_90(U8); 647 PSIMAGE_ROTATE_RIGHT_90(U16); 648 PSIMAGE_ROTATE_RIGHT_90(U32); 649 PSIMAGE_ROTATE_RIGHT_90(U64); 650 PSIMAGE_ROTATE_RIGHT_90(S8); 651 PSIMAGE_ROTATE_RIGHT_90(S16); 652 PSIMAGE_ROTATE_RIGHT_90(S32); 653 PSIMAGE_ROTATE_RIGHT_90(S64); 654 PSIMAGE_ROTATE_RIGHT_90(F32); 655 PSIMAGE_ROTATE_RIGHT_90(F64); 656 PSIMAGE_ROTATE_RIGHT_90(C32); 657 PSIMAGE_ROTATE_RIGHT_90(C64); 658 default: 659 psError(__func__,"Unsupported type (%d)",type); 660 psFree(out); 661 return NULL; 662 } 663 } else 664 if (fabsf(angle) < FLT_EPSILON) { 665 out = psImageCopy(out,in,in->type.type); 666 } else { 667 psElemType type = in->type.type; 668 int numRows = in->numRows; 669 int numCols = in->numCols; 670 double centerX = (float)(numCols) / 2.0f; 671 float centerY = (float)(numRows) / 2.0f; 672 float t = angle*(3.14159265358f/180.0f); 673 float cosT = cosf(t); 674 float sinT = sinf(t); 675 676 // calculate the corners of the rotated image so we know the proper output image size. 677 // x' = x cos(t) + y sin(t); i.e, x' = (x-centerX)*cosT + (y-centerY)*sinT; 678 // y' = y cos(t) - x sin(t); i.e. y' = (y-centerY)*cosT - (x-centerX)*sinT; 679 680 681 int outCols = ceil(abs(numCols*cosT)+abs(numRows*sinT))+1; 682 int outRows = ceil(abs(numCols*sinT)+abs(numRows*cosT))+1; 683 float minX = (float)outCols/-2.0f; 684 int intMinY = outRows/-2; 685 686 out = psImageRecycle(out,outCols,outRows,type); 687 688 /* optimized public domain rotation routine by Karl Lager 689 float cosT,sinT; 690 cosT = cos(t); 691 sinT = sin(t); 692 for (y = min_y; y <= max_y; y++) 693 { x' = min_x * cosT + y * sinT + x1'; 694 y' = y * cosT - min_x * sinT + y1'; 695 for (x = min_x; x <= max_x; x++) 696 { if (x', y') is in the bounds of the bitmap, 697 get pixel(x', y') and plot the pixel to 698 (x, y) on screen. 699 x' += cosT; 700 y' -= sinT; 701 } 702 } 703 */ 704 705 // precalculate some figures that are used within loop 706 float minXTimesCosTPlusCenterX = minX*cosT+centerX; 707 float CenterYMinusminXTimesSinT = centerY-minX*sinT; 708 709 #define PSIMAGE_ROTATE_ARBITRARY_LOOP(TYPE,MODE) { \ 710 if (unexposedValue < PS_MIN_##TYPE || unexposedValue > PS_MAX_##TYPE) { \ 711 psError(__func__,"The given unexposedValue (%g) is outside of the " \ 712 "image type's range (%g->%g).", \ 713 unexposedValue, (double)PS_MIN_##TYPE,(double)PS_MAX_##TYPE); \ 714 psFree(out); \ 715 out = NULL; \ 716 break; \ 717 } \ 718 float inX; \ 719 float inY; \ 720 ps##TYPE* outRow; \ 721 for (int y = 0; y < outRows; y++) { \ 722 inX = minXTimesCosTPlusCenterX + (y+intMinY) * sinT; \ 723 inY = CenterYMinusminXTimesSinT + (y+intMinY) * cosT; \ 724 outRow = out->data.TYPE[y]; \ 725 for (int x = 0; x < outCols; x++) { \ 726 outRow[x] = p_psImagePixelInterpolate##MODE##_##TYPE(in,inX,inY,unexposedValue); \ 727 inX += cosT; \ 728 inY -= sinT; \ 729 } \ 730 } \ 731 } 732 733 #define PSIMAGE_ROTATE_ARBITRARY_CASE(MODE) \ 734 case PS_INTERPOLATE_##MODE: \ 735 switch (type) { \ 736 case PS_TYPE_U8: \ 737 PSIMAGE_ROTATE_ARBITRARY_LOOP(U8,MODE); \ 738 break; \ 739 case PS_TYPE_U16: \ 740 PSIMAGE_ROTATE_ARBITRARY_LOOP(U16,MODE); \ 741 break; \ 742 case PS_TYPE_U32: \ 743 PSIMAGE_ROTATE_ARBITRARY_LOOP(U32,MODE); \ 744 break; \ 745 case PS_TYPE_U64: \ 746 PSIMAGE_ROTATE_ARBITRARY_LOOP(U64,MODE); \ 747 break; \ 748 case PS_TYPE_S8: \ 749 PSIMAGE_ROTATE_ARBITRARY_LOOP(S8,MODE); \ 750 break; \ 751 case PS_TYPE_S16: \ 752 PSIMAGE_ROTATE_ARBITRARY_LOOP(S16,MODE); \ 753 break; \ 754 case PS_TYPE_S32: \ 755 PSIMAGE_ROTATE_ARBITRARY_LOOP(S32,MODE); \ 756 break; \ 757 case PS_TYPE_S64: \ 758 PSIMAGE_ROTATE_ARBITRARY_LOOP(S64,MODE); \ 759 break; \ 760 case PS_TYPE_F32: \ 761 PSIMAGE_ROTATE_ARBITRARY_LOOP(F32,MODE); \ 762 break; \ 763 case PS_TYPE_F64: \ 764 PSIMAGE_ROTATE_ARBITRARY_LOOP(F64,MODE); \ 765 break; \ 766 case PS_TYPE_C32: \ 767 PSIMAGE_ROTATE_ARBITRARY_LOOP(C32,MODE); \ 768 break; \ 769 case PS_TYPE_C64: \ 770 PSIMAGE_ROTATE_ARBITRARY_LOOP(C64,MODE); \ 771 break; \ 772 default: \ 773 psError(__func__,"Image type (%d) not supported",type); \ 774 psFree(out); \ 775 out = NULL; \ 776 } \ 777 break; 778 779 switch (mode) { 780 PSIMAGE_ROTATE_ARBITRARY_CASE(FLAT); 781 PSIMAGE_ROTATE_ARBITRARY_CASE(BILINEAR); 782 default: 783 psError(__func__,"Unsupported interpolation mode (%d)",mode); 784 psFree(out); 785 out = NULL; 786 } 787 } 785 788 786 789 return out; -
trunk/psLib/src/image/psImageStats.c
r1341 r1385 271 271 if ((i != 0) && (j != 0)) { 272 272 coeffs->coeff[i][j]*= 4.0; 273 } else if ((i == 0) && (j == 0)) { 274 coeffs->coeff[i][j]*= 1.0; 275 } else { 276 coeffs->coeff[i][j]*= 2.0; 277 } 273 } else 274 if ((i == 0) && (j == 0)) { 275 coeffs->coeff[i][j]*= 1.0; 276 } else { 277 coeffs->coeff[i][j]*= 2.0; 278 } 278 279 } 279 280 } -
trunk/psLib/src/imageops/psImageStats.c
r1341 r1385 271 271 if ((i != 0) && (j != 0)) { 272 272 coeffs->coeff[i][j]*= 4.0; 273 } else if ((i == 0) && (j == 0)) { 274 coeffs->coeff[i][j]*= 1.0; 275 } else { 276 coeffs->coeff[i][j]*= 2.0; 277 } 273 } else 274 if ((i == 0) && (j == 0)) { 275 coeffs->coeff[i][j]*= 1.0; 276 } else { 277 coeffs->coeff[i][j]*= 2.0; 278 } 278 279 } 279 280 } -
trunk/psLib/src/math/psMatrix.c
r908 r1385 20 20 * @author Ross Harman, MHPCC 21 21 * 22 * @version $Revision: 1. 8$ $Name: not supported by cvs2svn $23 * @date $Date: 2004-0 6-08 01:57:52$22 * @version $Revision: 1.9 $ $Name: not supported by cvs2svn $ 23 * @date $Date: 2004-08-04 23:37:39 $ 24 24 * 25 25 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 475 475 PS_CHECK_ALLOC_VECTOR(outVector, inImage->numCols, inImage->type.type); 476 476 outVector->type.dimen = PS_DIMEN_TRANSV; 477 } else if(inImage->numCols == 1) { 478 // Create non-transposed column vector 479 PS_CHECK_ALLOC_VECTOR(outVector, inImage->numRows, inImage->type.type); 480 } else { 481 psError(__func__, "Image does not have dim with 1 col or 1 row: (%d x %d).", inImage->numRows, 482 inImage->numCols); 483 return outVector; 484 } 477 } else 478 if(inImage->numCols == 1) { 479 // Create non-transposed column vector 480 PS_CHECK_ALLOC_VECTOR(outVector, inImage->numRows, inImage->type.type); 481 } else { 482 psError(__func__, "Image does not have dim with 1 col or 1 row: (%d x %d).", inImage->numRows, 483 inImage->numCols); 484 return outVector; 485 } 485 486 486 487 PS_CHECK_NULL_VECTOR(outVector, outVector); … … 502 503 size = PSELEMTYPE_SIZEOF(inImage->type.type)*inImage->numRows; 503 504 504 } else if(outVector->type.dimen == PS_DIMEN_TRANSV) { 505 PS_CHECK_DIMEN_AND_TYPE(outVector, PS_DIMEN_TRANSV, outVector); 506 507 if(outVector->n == 0) { 508 outVector->n = inImage->numCols; 505 } else 506 if(outVector->type.dimen == PS_DIMEN_TRANSV) { 507 PS_CHECK_DIMEN_AND_TYPE(outVector, PS_DIMEN_TRANSV, outVector); 508 509 if(outVector->n == 0) { 510 outVector->n = inImage->numCols; 511 } 512 513 if(outVector->n != inImage->numCols) { 514 psError(__func__, "Image and vector sizes differ: (%d vs %d).", inImage->numCols, outVector->n); 515 return outVector; 516 } 517 518 size = PSELEMTYPE_SIZEOF(inImage->type.type)*inImage->numCols; 509 519 } 510 511 if(outVector->n != inImage->numCols) {512 psError(__func__, "Image and vector sizes differ: (%d vs %d).", inImage->numCols, outVector->n);513 return outVector;514 }515 516 size = PSELEMTYPE_SIZEOF(inImage->type.type)*inImage->numCols;517 }518 520 519 521 memcpy(outVector->data.V, inImage->data.V[0], size); … … 538 540 psError(__func__, "Image has more than 1 column: numCols = %d.", outImage->numCols); 539 541 return outImage; 540 } else if(outImage->numRows != inVector->n) { 541 psError(__func__, "Image and vector sizes differ: (%d vs %d).", outImage->numRows, inVector->n); 542 return outImage; 542 } else 543 if(outImage->numRows != inVector->n) { 544 psError(__func__, "Image and vector sizes differ: (%d vs %d).", outImage->numRows, inVector->n); 545 return outImage; 546 } 547 548 size = PSELEMTYPE_SIZEOF(outImage->type.type)*outImage->numRows; 549 550 } else 551 if(inVector->type.dimen == PS_DIMEN_TRANSV) { 552 PS_CHECK_DIMEN_AND_TYPE(inVector, PS_DIMEN_TRANSV, outImage); 553 PS_CHECK_SIZE_VECTOR(inVector, outImage); 554 PS_CHECK_ALLOC_IMAGE(outImage, inVector->n, 1, PS_TYPE_F64) 555 556 // More checks for PS_DIMEN_TRANSV 557 if(outImage->numRows > 1) { 558 psError(__func__, "Image has more than 1 row: numRows = %d.", outImage->numRows); 559 return outImage; 560 } else 561 if(outImage->numCols != inVector->n) { 562 psError(__func__, "Image and vector sizes differ: (%d vs %d).", outImage->numCols, inVector->n); 563 return outImage; 564 } 565 566 size = PSELEMTYPE_SIZEOF(outImage->type.type)*outImage->numCols; 543 567 } 544 545 size = PSELEMTYPE_SIZEOF(outImage->type.type)*outImage->numRows;546 547 } else if(inVector->type.dimen == PS_DIMEN_TRANSV) {548 PS_CHECK_DIMEN_AND_TYPE(inVector, PS_DIMEN_TRANSV, outImage);549 PS_CHECK_SIZE_VECTOR(inVector, outImage);550 PS_CHECK_ALLOC_IMAGE(outImage, inVector->n, 1, PS_TYPE_F64)551 552 // More checks for PS_DIMEN_TRANSV553 if(outImage->numRows > 1) {554 psError(__func__, "Image has more than 1 row: numRows = %d.", outImage->numRows);555 return outImage;556 } else if(outImage->numCols != inVector->n) {557 psError(__func__, "Image and vector sizes differ: (%d vs %d).", outImage->numCols, inVector->n);558 return outImage;559 }560 561 size = PSELEMTYPE_SIZEOF(outImage->type.type)*outImage->numCols;562 }563 568 564 569 PS_CHECK_NULL_IMAGE(outImage, outImage); -
trunk/psLib/src/math/psMinimize.c
r1345 r1385 9 9 * @author George Gusciora, MHPCC 10 10 * 11 * @version $Revision: 1.2 5$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-0 7-30 00:39:14$11 * @version $Revision: 1.26 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-08-04 23:37:39 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/math/psPolynomial.c
r1342 r1385 7 7 * polynomials. It also contains a Gaussian functions. 8 8 * 9 * @version $Revision: 1.1 8$ $Name: not supported by cvs2svn $10 * @date $Date: 2004-0 7-29 23:34:24$9 * @version $Revision: 1.19 $ $Name: not supported by cvs2svn $ 10 * @date $Date: 2004-08-04 23:37:39 $ 11 11 * 12 12 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/math/psPolynomial.h
r1382 r1385 12 12 * @author George Gusciora, MHPCC 13 13 * 14 * @version $Revision: 1.1 2$ $Name: not supported by cvs2svn $15 * @date $Date: 2004-08-04 2 2:11:09 $14 * @version $Revision: 1.13 $ $Name: not supported by cvs2svn $ 15 * @date $Date: 2004-08-04 23:37:39 $ 16 16 * 17 17 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 39 39 bool normal ///< Indicates whether result should be normalized 40 40 ); 41 42 41 42 43 43 /** Produce a vector of random numbers from a Gaussian distribution with 44 44 the specified mean and sigma */ … … 46 46 float sigma, ///< The sigma of the Gaussian 47 47 int Npts ); ///< The size of the vector 48 49 50 51 52 48 49 50 51 52 53 53 /** One-dimensional polynomial */ 54 54 typedef struct 55 {56 int n; ///< Number of terms57 float *coeff; ///< Coefficients58 float *coeffErr; ///< Error in coefficients59 char *mask; ///< Coefficient mask60 }55 { 56 int n; ///< Number of terms 57 float *coeff; ///< Coefficients 58 float *coeffErr; ///< Error in coefficients 59 char *mask; ///< Coefficient mask 60 } 61 61 psPolynomial1D; 62 62 63 63 /** Two-dimensional polynomial */ 64 64 typedef struct 65 {66 int nX, nY; ///< Number of terms in x and y67 float **coeff; ///< Coefficients68 float **coeffErr; ///< Error in coefficients69 char **mask; ///< Coefficients mask70 }65 { 66 int nX, nY; ///< Number of terms in x and y 67 float **coeff; ///< Coefficients 68 float **coeffErr; ///< Error in coefficients 69 char **mask; ///< Coefficients mask 70 } 71 71 psPolynomial2D; 72 72 73 73 /** Three-dimensional polynomial */ 74 74 typedef struct 75 {76 int nX, nY, nZ; ///< Number of terms in x, y and z77 float ***coeff; ///< Coefficients78 float ***coeffErr; ///< Error in coefficients79 char ***mask; ///< Coefficients mask80 }75 { 76 int nX, nY, nZ; ///< Number of terms in x, y and z 77 float ***coeff; ///< Coefficients 78 float ***coeffErr; ///< Error in coefficients 79 char ***mask; ///< Coefficients mask 80 } 81 81 psPolynomial3D; 82 82 83 83 /** Four-dimensional polynomial */ 84 84 typedef struct 85 {86 int nW, nX, nY, nZ; ///< Number of terms in w, x, y and z87 float ****coeff; ///< Coefficients88 float ****coeffErr; ///< Error in coefficients89 char ****mask; ///< Coefficients mask90 }85 { 86 int nW, nX, nY, nZ; ///< Number of terms in w, x, y and z 87 float ****coeff; ///< Coefficients 88 float ****coeffErr; ///< Error in coefficients 89 char ****mask; ///< Coefficients mask 90 } 91 91 psPolynomial4D; 92 92 … … 106 106 psPolynomial4D *psPolynomial4DAlloc( int nW, int nX, int nY, int nZ ///< Number of terms in w, x, y and z 107 107 ); 108 108 109 109 /** Evaluate 1D polynomial */ 110 110 float … … 112 112 const psPolynomial1D *myPoly ///< Coefficients for the polynomial 113 113 ); 114 114 115 115 /** Evaluate 2D polynomial */ 116 116 float … … 119 119 const psPolynomial2D *myPoly ///< Coefficients for the polynomial 120 120 ); 121 121 122 122 /** Evaluate 3D polynomial */ 123 123 float … … 127 127 const psPolynomial3D *myPoly ///< Coefficients for the polynomial 128 128 ); 129 129 130 130 /** Evaluate 4D polynomial */ 131 131 float … … 136 136 const psPolynomial4D *myPoly ///< Coefficients for the polynomial 137 137 ); 138 138 139 139 /*****************************************************************************/ 140 140 … … 143 143 /** Double-precision one-dimensional polynomial */ 144 144 typedef struct 145 {146 int n; ///< Number of terms147 double *coeff; ///< Coefficients148 double *coeffErr; ///< Error in coefficients149 char *mask; ///< Coefficient mask150 }145 { 146 int n; ///< Number of terms 147 double *coeff; ///< Coefficients 148 double *coeffErr; ///< Error in coefficients 149 char *mask; ///< Coefficient mask 150 } 151 151 psDPolynomial1D; 152 152 153 153 /** Double-precision two-dimensional polynomial */ 154 154 typedef struct 155 {156 int nX, nY; ///< Number of terms in x and y157 double **coeff; ///< Coefficients158 double **coeffErr; ///< Error in coefficients159 char **mask; ///< Coefficients mask160 }155 { 156 int nX, nY; ///< Number of terms in x and y 157 double **coeff; ///< Coefficients 158 double **coeffErr; ///< Error in coefficients 159 char **mask; ///< Coefficients mask 160 } 161 161 psDPolynomial2D; 162 162 163 163 /** Double-precision three-dimensional polynomial */ 164 164 typedef struct 165 {166 int nX, nY, nZ; ///< Number of terms in x, y and z167 double ***coeff; ///< Coefficients168 double ***coeffErr; ///< Error in coefficients169 char ***mask; ///< Coefficient mask170 }165 { 166 int nX, nY, nZ; ///< Number of terms in x, y and z 167 double ***coeff; ///< Coefficients 168 double ***coeffErr; ///< Error in coefficients 169 char ***mask; ///< Coefficient mask 170 } 171 171 psDPolynomial3D; 172 172 173 173 /** Double-precision four-dimensional polynomial */ 174 174 typedef struct 175 {176 int nW, nX, nY, nZ; ///< Number of terms in w, x, y and z177 double ****coeff; ///< Coefficients178 double ****coeffErr; ///< Error in coefficients179 char ****mask; ///< Coefficients mask180 }175 { 176 int nW, nX, nY, nZ; ///< Number of terms in w, x, y and z 177 double ****coeff; ///< Coefficients 178 double ****coeffErr; ///< Error in coefficients 179 char ****mask; ///< Coefficients mask 180 } 181 181 psDPolynomial4D; 182 182 … … 193 193 psDPolynomial4D *psDPolynomial4DAlloc( int nW, int nX, int nY, int nZ ///< Number of terms in w, x, y and z 194 194 ); 195 195 196 196 /** Evaluate 1D polynomial (double precision) */ 197 197 double … … 199 199 const psDPolynomial1D *myPoly ///< Coefficients for the polynomial 200 200 ); 201 201 202 202 /** Evaluate 2D polynomial (double precision) */ 203 203 double … … 206 206 const psDPolynomial2D *myPoly ///< Coefficients for the polynomial 207 207 ); 208 208 209 209 /** Evaluate 3D polynomial (double precision) */ 210 210 double … … 214 214 const psDPolynomial3D *myPoly ///< Coefficients for the polynomial 215 215 ); 216 216 217 217 /** Evaluate 4D polynomial (double precision) */ 218 218 double … … 223 223 const psDPolynomial4D *myPoly ///< Coefficients for the polynomial 224 224 ); 225 225 226 226 /* \} */ // End of MathGroup Functions 227 227 -
trunk/psLib/src/math/psSpline.c
r1342 r1385 7 7 * polynomials. It also contains a Gaussian functions. 8 8 * 9 * @version $Revision: 1.1 8$ $Name: not supported by cvs2svn $10 * @date $Date: 2004-0 7-29 23:34:24$9 * @version $Revision: 1.19 $ $Name: not supported by cvs2svn $ 10 * @date $Date: 2004-08-04 23:37:39 $ 11 11 * 12 12 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/math/psSpline.h
r1382 r1385 12 12 * @author George Gusciora, MHPCC 13 13 * 14 * @version $Revision: 1.1 2$ $Name: not supported by cvs2svn $15 * @date $Date: 2004-08-04 2 2:11:09 $14 * @version $Revision: 1.13 $ $Name: not supported by cvs2svn $ 15 * @date $Date: 2004-08-04 23:37:39 $ 16 16 * 17 17 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 39 39 bool normal ///< Indicates whether result should be normalized 40 40 ); 41 42 41 42 43 43 /** Produce a vector of random numbers from a Gaussian distribution with 44 44 the specified mean and sigma */ … … 46 46 float sigma, ///< The sigma of the Gaussian 47 47 int Npts ); ///< The size of the vector 48 49 50 51 52 48 49 50 51 52 53 53 /** One-dimensional polynomial */ 54 54 typedef struct 55 {56 int n; ///< Number of terms57 float *coeff; ///< Coefficients58 float *coeffErr; ///< Error in coefficients59 char *mask; ///< Coefficient mask60 }55 { 56 int n; ///< Number of terms 57 float *coeff; ///< Coefficients 58 float *coeffErr; ///< Error in coefficients 59 char *mask; ///< Coefficient mask 60 } 61 61 psPolynomial1D; 62 62 63 63 /** Two-dimensional polynomial */ 64 64 typedef struct 65 {66 int nX, nY; ///< Number of terms in x and y67 float **coeff; ///< Coefficients68 float **coeffErr; ///< Error in coefficients69 char **mask; ///< Coefficients mask70 }65 { 66 int nX, nY; ///< Number of terms in x and y 67 float **coeff; ///< Coefficients 68 float **coeffErr; ///< Error in coefficients 69 char **mask; ///< Coefficients mask 70 } 71 71 psPolynomial2D; 72 72 73 73 /** Three-dimensional polynomial */ 74 74 typedef struct 75 {76 int nX, nY, nZ; ///< Number of terms in x, y and z77 float ***coeff; ///< Coefficients78 float ***coeffErr; ///< Error in coefficients79 char ***mask; ///< Coefficients mask80 }75 { 76 int nX, nY, nZ; ///< Number of terms in x, y and z 77 float ***coeff; ///< Coefficients 78 float ***coeffErr; ///< Error in coefficients 79 char ***mask; ///< Coefficients mask 80 } 81 81 psPolynomial3D; 82 82 83 83 /** Four-dimensional polynomial */ 84 84 typedef struct 85 {86 int nW, nX, nY, nZ; ///< Number of terms in w, x, y and z87 float ****coeff; ///< Coefficients88 float ****coeffErr; ///< Error in coefficients89 char ****mask; ///< Coefficients mask90 }85 { 86 int nW, nX, nY, nZ; ///< Number of terms in w, x, y and z 87 float ****coeff; ///< Coefficients 88 float ****coeffErr; ///< Error in coefficients 89 char ****mask; ///< Coefficients mask 90 } 91 91 psPolynomial4D; 92 92 … … 106 106 psPolynomial4D *psPolynomial4DAlloc( int nW, int nX, int nY, int nZ ///< Number of terms in w, x, y and z 107 107 ); 108 108 109 109 /** Evaluate 1D polynomial */ 110 110 float … … 112 112 const psPolynomial1D *myPoly ///< Coefficients for the polynomial 113 113 ); 114 114 115 115 /** Evaluate 2D polynomial */ 116 116 float … … 119 119 const psPolynomial2D *myPoly ///< Coefficients for the polynomial 120 120 ); 121 121 122 122 /** Evaluate 3D polynomial */ 123 123 float … … 127 127 const psPolynomial3D *myPoly ///< Coefficients for the polynomial 128 128 ); 129 129 130 130 /** Evaluate 4D polynomial */ 131 131 float … … 136 136 const psPolynomial4D *myPoly ///< Coefficients for the polynomial 137 137 ); 138 138 139 139 /*****************************************************************************/ 140 140 … … 143 143 /** Double-precision one-dimensional polynomial */ 144 144 typedef struct 145 {146 int n; ///< Number of terms147 double *coeff; ///< Coefficients148 double *coeffErr; ///< Error in coefficients149 char *mask; ///< Coefficient mask150 }145 { 146 int n; ///< Number of terms 147 double *coeff; ///< Coefficients 148 double *coeffErr; ///< Error in coefficients 149 char *mask; ///< Coefficient mask 150 } 151 151 psDPolynomial1D; 152 152 153 153 /** Double-precision two-dimensional polynomial */ 154 154 typedef struct 155 {156 int nX, nY; ///< Number of terms in x and y157 double **coeff; ///< Coefficients158 double **coeffErr; ///< Error in coefficients159 char **mask; ///< Coefficients mask160 }155 { 156 int nX, nY; ///< Number of terms in x and y 157 double **coeff; ///< Coefficients 158 double **coeffErr; ///< Error in coefficients 159 char **mask; ///< Coefficients mask 160 } 161 161 psDPolynomial2D; 162 162 163 163 /** Double-precision three-dimensional polynomial */ 164 164 typedef struct 165 {166 int nX, nY, nZ; ///< Number of terms in x, y and z167 double ***coeff; ///< Coefficients168 double ***coeffErr; ///< Error in coefficients169 char ***mask; ///< Coefficient mask170 }165 { 166 int nX, nY, nZ; ///< Number of terms in x, y and z 167 double ***coeff; ///< Coefficients 168 double ***coeffErr; ///< Error in coefficients 169 char ***mask; ///< Coefficient mask 170 } 171 171 psDPolynomial3D; 172 172 173 173 /** Double-precision four-dimensional polynomial */ 174 174 typedef struct 175 {176 int nW, nX, nY, nZ; ///< Number of terms in w, x, y and z177 double ****coeff; ///< Coefficients178 double ****coeffErr; ///< Error in coefficients179 char ****mask; ///< Coefficients mask180 }175 { 176 int nW, nX, nY, nZ; ///< Number of terms in w, x, y and z 177 double ****coeff; ///< Coefficients 178 double ****coeffErr; ///< Error in coefficients 179 char ****mask; ///< Coefficients mask 180 } 181 181 psDPolynomial4D; 182 182 … … 193 193 psDPolynomial4D *psDPolynomial4DAlloc( int nW, int nX, int nY, int nZ ///< Number of terms in w, x, y and z 194 194 ); 195 195 196 196 /** Evaluate 1D polynomial (double precision) */ 197 197 double … … 199 199 const psDPolynomial1D *myPoly ///< Coefficients for the polynomial 200 200 ); 201 201 202 202 /** Evaluate 2D polynomial (double precision) */ 203 203 double … … 206 206 const psDPolynomial2D *myPoly ///< Coefficients for the polynomial 207 207 ); 208 208 209 209 /** Evaluate 3D polynomial (double precision) */ 210 210 double … … 214 214 const psDPolynomial3D *myPoly ///< Coefficients for the polynomial 215 215 ); 216 216 217 217 /** Evaluate 4D polynomial (double precision) */ 218 218 double … … 223 223 const psDPolynomial4D *myPoly ///< Coefficients for the polynomial 224 224 ); 225 225 226 226 /* \} */ // End of MathGroup Functions 227 227 -
trunk/psLib/src/math/psStats.c
r1361 r1385 36 36 unsigned int maskVal, 37 37 psStats *stats ); 38 38 39 39 /** Preprocessor macro to generate error on an incorrect type */ 40 40 #define PS_CHECK_VECTOR_TYPE(NAME, TYPE) \ 41 41 if (NAME->type.type != TYPE) { \ 42 psError(__func__,"Invalid operation: %s has incorrect type.", #NAME); \43 }44 42 psError(__func__,"Invalid operation: %s has incorrect type.", #NAME); \ 43 } 44 45 45 /** Preprocessor macro to generate error on a NULL vector */ 46 46 #define PS_CHECK_NULL_VECTOR(NAME) \ 47 47 if (NAME == NULL || NAME->data.V == NULL) { \ 48 psError(__func__,"Invalid operation: %s or its data is NULL.", #NAME); \49 }50 48 psError(__func__,"Invalid operation: %s or its data is NULL.", #NAME); \ 49 } 50 51 51 /** Preprocessor macro to generate error for zero length vector */ 52 52 #define PS_CHECK_EMPTY_VECTOR(NAME) \ 53 53 if (NAME->n < 1) { \ 54 psError(__func__,"Invalid operation: %s has zero n value.", #NAME); \55 }56 54 psError(__func__,"Invalid operation: %s has zero n value.", #NAME); \ 55 } 56 57 57 /** Preprocessor macro to generate error on differing size vectors */ 58 58 #define PS_CHECK_VECTOR_SIZE_EQUAL(VEC1, VEC2) \ 59 59 if (VEC1->n != VEC2->n) { \ 60 psError(__func__,"Vector %s has size %d, Vector %s has size %d.", #VEC1, VEC1->n, #VEC2, VEC2->n); \61 }62 60 psError(__func__,"Vector %s has size %d, Vector %s has size %d.", #VEC1, VEC1->n, #VEC2, VEC2->n); \ 61 } 62 63 63 #define PS_PRINT_VECTOR(NAME) \ 64 64 for (int my_i=0;my_i<NAME->n;my_i++) { \ 65 printf("%s->data.F32[%d] is %f\n", #NAME, my_i, NAME->data.F32[my_i]); \66 } \65 printf("%s->data.F32[%d] is %f\n", #NAME, my_i, NAME->data.F32[my_i]); \ 66 } \ 67 67 printf("\n"); \ 68 68 … … 92 92 switch ( stats->options & 93 93 ~ ( PS_STAT_USE_RANGE | PS_STAT_USE_BINSIZE | PS_STAT_ROBUST_FOR_SAMPLE ) ) { 94 case PS_STAT_SAMPLE_MEAN:95 *value = stats->sampleMean;96 return true;97 98 case PS_STAT_SAMPLE_MEDIAN:99 *value = stats->sampleMedian;100 return true;101 102 case PS_STAT_SAMPLE_STDEV:103 *value = stats->sampleStdev;104 return true;105 106 case PS_STAT_ROBUST_MEAN:107 *value = stats->robustMean;108 return true;109 110 case PS_STAT_ROBUST_MEDIAN:111 *value = stats->robustMedian;112 return true;113 114 case PS_STAT_ROBUST_MODE:115 *value = stats->robustMode;116 return true;117 118 case PS_STAT_ROBUST_STDEV:119 *value = stats->robustStdev;120 return true;121 122 case PS_STAT_CLIPPED_MEAN:123 *value = stats->clippedMean;124 return true;125 126 case PS_STAT_CLIPPED_STDEV:127 *value = stats->clippedStdev;128 return true;129 130 case PS_STAT_MAX:131 *value = stats->max;132 return true;133 134 case PS_STAT_MIN:135 *value = stats->min;136 return true;137 138 default:139 return false;140 }94 case PS_STAT_SAMPLE_MEAN: 95 *value = stats->sampleMean; 96 return true; 97 98 case PS_STAT_SAMPLE_MEDIAN: 99 *value = stats->sampleMedian; 100 return true; 101 102 case PS_STAT_SAMPLE_STDEV: 103 *value = stats->sampleStdev; 104 return true; 105 106 case PS_STAT_ROBUST_MEAN: 107 *value = stats->robustMean; 108 return true; 109 110 case PS_STAT_ROBUST_MEDIAN: 111 *value = stats->robustMedian; 112 return true; 113 114 case PS_STAT_ROBUST_MODE: 115 *value = stats->robustMode; 116 return true; 117 118 case PS_STAT_ROBUST_STDEV: 119 *value = stats->robustStdev; 120 return true; 121 122 case PS_STAT_CLIPPED_MEAN: 123 *value = stats->clippedMean; 124 return true; 125 126 case PS_STAT_CLIPPED_STDEV: 127 *value = stats->clippedStdev; 128 return true; 129 130 case PS_STAT_MAX: 131 *value = stats->max; 132 return true; 133 134 case PS_STAT_MIN: 135 *value = stats->min; 136 return true; 137 138 default: 139 return false; 140 } 141 141 } 142 142 … … 153 153 { 154 154 int i = 0; // Loop index variable. 155 155 156 156 for ( i = 0;i < myVector->n;i++ ) { 157 if ( maskVector != NULL )158 printf( "Element %d is %f (mask is %d)\n", i, myVector->data.F32[ i ], maskVector->data.U8[ i ] );159 else160 printf( "Element %d is %f\n", i, myVector->data.F32[ i ] );161 }157 if ( maskVector != NULL ) 158 printf( "Element %d is %f (mask is %d)\n", i, myVector->data.F32[ i ], maskVector->data.U8[ i ] ); 159 else 160 printf( "Element %d is %f\n", i, myVector->data.F32[ i ] ); 161 } 162 162 } 163 163 … … 204 204 float rangeMin = 0.0; // Exclude data below this 205 205 float rangeMax = 0.0; // Exclude date above this 206 206 207 207 // If PS_STAT_USE_RANGE is requested, then we enter a slightly different 208 208 // loop. 209 209 if ( stats->options & PS_STAT_USE_RANGE ) { 210 rangeMin = stats->min; 211 rangeMax = stats->max; 212 if ( maskVector != NULL ) { 213 for ( i = 0;i < myVector->n;i++ ) { 214 // Check if the data is with the specified range 215 if ( !( maskVal & maskVector->data.U8[ i ] ) && 216 ( rangeMin <= myVector->data.F32[ i ] ) && 217 ( myVector->data.F32[ i ] <= rangeMax ) ) { 218 mean += myVector->data.F32[ i ]; 219 count++; 220 } 221 } 222 mean /= ( float ) count; 223 } else { 224 for ( i = 0;i < myVector->n;i++ ) { 225 if ( ( rangeMin <= myVector->data.F32[ i ] ) && 226 ( myVector->data.F32[ i ] <= rangeMax ) ) { 227 mean += myVector->data.F32[ i ]; 228 count++; 229 } 230 } 231 mean /= ( float ) count; 232 } 210 rangeMin = stats->min; 211 rangeMax = stats->max; 212 if ( maskVector != NULL ) { 213 for ( i = 0;i < myVector->n;i++ ) { 214 // Check if the data is with the specified range 215 if ( !( maskVal & maskVector->data.U8[ i ] ) && 216 ( rangeMin <= myVector->data.F32[ i ] ) && 217 ( myVector->data.F32[ i ] <= rangeMax ) ) { 218 mean += myVector->data.F32[ i ]; 219 count++; 220 } 221 } 222 mean /= ( float ) count; 233 223 } else { 234 if ( maskVector != NULL ) { 235 for ( i = 0;i < myVector->n;i++ ) { 236 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 237 mean += myVector->data.F32[ i ]; 238 count++; 239 } 240 } 241 mean /= ( float ) count; 242 } else { 243 for ( i = 0;i < myVector->n;i++ ) { 244 mean += myVector->data.F32[ i ]; 245 } 246 mean /= ( float ) myVector->n; 247 } 248 } 249 224 for ( i = 0;i < myVector->n;i++ ) { 225 if ( ( rangeMin <= myVector->data.F32[ i ] ) && 226 ( myVector->data.F32[ i ] <= rangeMax ) ) { 227 mean += myVector->data.F32[ i ]; 228 count++; 229 } 230 } 231 mean /= ( float ) count; 232 } 233 } else { 234 if ( maskVector != NULL ) { 235 for ( i = 0;i < myVector->n;i++ ) { 236 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 237 mean += myVector->data.F32[ i ]; 238 count++; 239 } 240 } 241 mean /= ( float ) count; 242 } else { 243 for ( i = 0;i < myVector->n;i++ ) { 244 mean += myVector->data.F32[ i ]; 245 } 246 mean /= ( float ) myVector->n; 247 } 248 } 249 250 250 stats->sampleMean = mean; 251 251 } … … 271 271 float rangeMin = 0.0; // Exclude data below this 272 272 float rangeMax = 0.0; // Exclude date above this 273 273 274 274 // If PS_STAT_USE_RANGE is requested, then we enter a different loop. 275 275 if ( stats->options & PS_STAT_USE_RANGE ) { 276 rangeMin = stats->min; 277 rangeMax = stats->max; 278 if ( maskVector != NULL ) { 279 for ( i = 0;i < myVector->n;i++ ) { 280 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 281 if ( ( myVector->data.F32[ i ] > max ) && 282 ( rangeMin <= myVector->data.F32[ i ] ) && 283 ( myVector->data.F32[ i ] <= rangeMax ) ) { 284 max = myVector->data.F32[ i ]; 285 } 286 } 287 } 288 } else { 289 for ( i = 0;i < myVector->n;i++ ) { 290 if ( ( myVector->data.F32[ i ] > max ) && 291 ( rangeMin <= myVector->data.F32[ i ] ) && 292 ( myVector->data.F32[ i ] <= rangeMax ) ) { 293 max = myVector->data.F32[ i ]; 294 } 295 } 296 } 276 rangeMin = stats->min; 277 rangeMax = stats->max; 278 if ( maskVector != NULL ) { 279 for ( i = 0;i < myVector->n;i++ ) { 280 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 281 if ( ( myVector->data.F32[ i ] > max ) && 282 ( rangeMin <= myVector->data.F32[ i ] ) && 283 ( myVector->data.F32[ i ] <= rangeMax ) ) { 284 max = myVector->data.F32[ i ]; 285 } 286 } 287 } 297 288 } else { 298 if ( maskVector != NULL ) { 299 for ( i = 0;i < myVector->n;i++ ) { 300 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 301 if ( myVector->data.F32[ i ] > max ) { 302 max = myVector->data.F32[ i ]; 303 } 304 } 305 } 306 } else { 307 for ( i = 0;i < myVector->n;i++ ) { 308 if ( myVector->data.F32[ i ] > max ) { 309 max = myVector->data.F32[ i ]; 310 } 311 } 312 } 313 } 314 289 for ( i = 0;i < myVector->n;i++ ) { 290 if ( ( myVector->data.F32[ i ] > max ) && 291 ( rangeMin <= myVector->data.F32[ i ] ) && 292 ( myVector->data.F32[ i ] <= rangeMax ) ) { 293 max = myVector->data.F32[ i ]; 294 } 295 } 296 } 297 } else { 298 if ( maskVector != NULL ) { 299 for ( i = 0;i < myVector->n;i++ ) { 300 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 301 if ( myVector->data.F32[ i ] > max ) { 302 max = myVector->data.F32[ i ]; 303 } 304 } 305 } 306 } else { 307 for ( i = 0;i < myVector->n;i++ ) { 308 if ( myVector->data.F32[ i ] > max ) { 309 max = myVector->data.F32[ i ]; 310 } 311 } 312 } 313 } 314 315 315 stats->max = max; 316 316 } … … 336 336 float rangeMin = 0.0; // Exclude data below this 337 337 float rangeMax = 0.0; // Exclude date above this 338 338 339 339 if ( stats->options & PS_STAT_USE_RANGE ) { 340 rangeMin = stats->min; 341 rangeMax = stats->max; 342 if ( maskVector != NULL ) { 343 for ( i = 0;i < myVector->n;i++ ) { 344 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 345 if ( ( myVector->data.F32[ i ] < min ) && 346 ( rangeMin <= myVector->data.F32[ i ] ) && 347 ( myVector->data.F32[ i ] <= rangeMax ) ) { 348 min = myVector->data.F32[ i ]; 349 } 350 } 351 } 352 } else { 353 for ( i = 0;i < myVector->n;i++ ) { 354 if ( ( myVector->data.F32[ i ] < min ) && 355 ( rangeMin <= myVector->data.F32[ i ] ) && 356 ( myVector->data.F32[ i ] <= rangeMax ) ) { 357 min = myVector->data.F32[ i ]; 358 } 359 } 360 } 340 rangeMin = stats->min; 341 rangeMax = stats->max; 342 if ( maskVector != NULL ) { 343 for ( i = 0;i < myVector->n;i++ ) { 344 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 345 if ( ( myVector->data.F32[ i ] < min ) && 346 ( rangeMin <= myVector->data.F32[ i ] ) && 347 ( myVector->data.F32[ i ] <= rangeMax ) ) { 348 min = myVector->data.F32[ i ]; 349 } 350 } 351 } 361 352 } else { 362 if ( maskVector != NULL ) { 363 for ( i = 0;i < myVector->n;i++ ) { 364 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 365 if ( myVector->data.F32[ i ] < min ) { 366 min = myVector->data.F32[ i ]; 367 } 368 } 369 } 370 } else { 371 for ( i = 0;i < myVector->n;i++ ) { 372 if ( myVector->data.F32[ i ] < min ) { 373 min = myVector->data.F32[ i ]; 374 } 375 } 376 } 377 } 378 353 for ( i = 0;i < myVector->n;i++ ) { 354 if ( ( myVector->data.F32[ i ] < min ) && 355 ( rangeMin <= myVector->data.F32[ i ] ) && 356 ( myVector->data.F32[ i ] <= rangeMax ) ) { 357 min = myVector->data.F32[ i ]; 358 } 359 } 360 } 361 } else { 362 if ( maskVector != NULL ) { 363 for ( i = 0;i < myVector->n;i++ ) { 364 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 365 if ( myVector->data.F32[ i ] < min ) { 366 min = myVector->data.F32[ i ]; 367 } 368 } 369 } 370 } else { 371 for ( i = 0;i < myVector->n;i++ ) { 372 if ( myVector->data.F32[ i ] < min ) { 373 min = myVector->data.F32[ i ]; 374 } 375 } 376 } 377 } 378 379 379 stats->min = min; 380 380 } … … 401 401 float rangeMin = 0.0; // Exclude data below this 402 402 float rangeMax = 0.0; // Exclude date above this 403 403 404 404 if ( stats->options & PS_STAT_USE_RANGE ) { 405 rangeMin = stats->min; 406 rangeMax = stats->max; 407 if ( maskVector != NULL ) { 408 for ( i = 0;i < myVector->n;i++ ) { 409 if ( !( maskVal & maskVector->data.U8[ i ] ) && 410 ( rangeMin <= myVector->data.F32[ i ] ) && 411 ( myVector->data.F32[ i ] <= rangeMax ) ) { 412 numData++; 413 } 414 } 415 } else { 416 for ( i = 0;i < myVector->n;i++ ) { 417 if ( ( rangeMin <= myVector->data.F32[ i ] ) && 418 ( myVector->data.F32[ i ] <= rangeMax ) ) { 419 numData++; 420 } 421 } 422 } 405 rangeMin = stats->min; 406 rangeMax = stats->max; 407 if ( maskVector != NULL ) { 408 for ( i = 0;i < myVector->n;i++ ) { 409 if ( !( maskVal & maskVector->data.U8[ i ] ) && 410 ( rangeMin <= myVector->data.F32[ i ] ) && 411 ( myVector->data.F32[ i ] <= rangeMax ) ) { 412 numData++; 413 } 414 } 423 415 } else { 424 rangeMin = stats->min; 425 rangeMax = stats->max; 426 if ( maskVector != NULL ) { 427 for ( i = 0;i < myVector->n;i++ ) { 428 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 429 numData++; 430 } 431 } 432 } else { 433 numData = myVector->n; 434 } 435 } 416 for ( i = 0;i < myVector->n;i++ ) { 417 if ( ( rangeMin <= myVector->data.F32[ i ] ) && 418 ( myVector->data.F32[ i ] <= rangeMax ) ) { 419 numData++; 420 } 421 } 422 } 423 } else { 424 rangeMin = stats->min; 425 rangeMax = stats->max; 426 if ( maskVector != NULL ) { 427 for ( i = 0;i < myVector->n;i++ ) { 428 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 429 numData++; 430 } 431 } 432 } else { 433 numData = myVector->n; 434 } 435 } 436 436 return ( numData ); 437 437 } … … 462 462 float rangeMin = 0.0; // Exclude data below this 463 463 float rangeMax = 0.0; // Exclude date above this 464 465 464 465 466 466 // Determine if the number of data points exceed a threshold which will 467 467 // cause to generate robust stats, as opposed to exact stats. … … 488 488 } 489 489 */ 490 490 491 491 // Determine how many data points fit inside this min/max range 492 492 // and are not masked, IF the maskVector is not NULL> 493 493 nValues = p_psVectorNValues( myVector, maskVector, maskVal, stats ); 494 494 495 495 // Allocate temporary vectors for the data. 496 496 unsortedVector = psVectorAlloc( nValues, PS_TYPE_F32 ); 497 497 unsortedVector->n = unsortedVector->nalloc; 498 498 499 499 sortedVector = psVectorAlloc( nValues, PS_TYPE_F32 ); 500 500 sortedVector->n = sortedVector->nalloc; 501 501 502 502 // Determine if we must only use data points within a min/max range. 503 503 if ( stats->options & PS_STAT_USE_RANGE ) { 504 rangeMin = stats->min; 505 rangeMax = stats->max; 506 507 // Store all non-masked data points within the min/max range 508 // into the temporary vectors. 509 count = 0; 510 if ( maskVector != NULL ) { 511 for ( i = 0;i < myVector->n;i++ ) { 512 if ( !( maskVal & maskVector->data.U8[ i ] ) && 513 ( rangeMin <= myVector->data.F32[ i ] ) && 514 ( myVector->data.F32[ i ] <= rangeMax ) ) { 515 unsortedVector->data.F32[ count++ ] = maskVector->data.F32[ i ]; 516 } 517 } 518 } else { 519 for ( i = 0;i < myVector->n;i++ ) { 520 if ( ( rangeMin <= myVector->data.F32[ i ] ) && 521 ( myVector->data.F32[ i ] <= rangeMax ) ) { 522 unsortedVector->data.F32[ count++ ] = myVector->data.F32[ i ]; 523 } 524 } 525 } 504 rangeMin = stats->min; 505 rangeMax = stats->max; 506 507 // Store all non-masked data points within the min/max range 508 // into the temporary vectors. 509 count = 0; 510 if ( maskVector != NULL ) { 511 for ( i = 0;i < myVector->n;i++ ) { 512 if ( !( maskVal & maskVector->data.U8[ i ] ) && 513 ( rangeMin <= myVector->data.F32[ i ] ) && 514 ( myVector->data.F32[ i ] <= rangeMax ) ) { 515 unsortedVector->data.F32[ count++ ] = maskVector->data.F32[ i ]; 516 } 517 } 526 518 } else { 527 // Store all non-masked data points into the temporary vectors. 528 count = 0; 529 if ( maskVector != NULL ) { 530 for ( i = 0;i < myVector->n;i++ ) { 531 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 532 unsortedVector->data.F32[ count++ ] = myVector->data.F32[ i ]; 533 } 534 } 535 } else { 536 for ( i = 0;i < myVector->n;i++ ) { 537 unsortedVector->data.F32[ i ] = myVector->data.F32[ i ]; 538 } 539 } 540 } 519 for ( i = 0;i < myVector->n;i++ ) { 520 if ( ( rangeMin <= myVector->data.F32[ i ] ) && 521 ( myVector->data.F32[ i ] <= rangeMax ) ) { 522 unsortedVector->data.F32[ count++ ] = myVector->data.F32[ i ]; 523 } 524 } 525 } 526 } else { 527 // Store all non-masked data points into the temporary vectors. 528 count = 0; 529 if ( maskVector != NULL ) { 530 for ( i = 0;i < myVector->n;i++ ) { 531 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 532 unsortedVector->data.F32[ count++ ] = myVector->data.F32[ i ]; 533 } 534 } 535 } else { 536 for ( i = 0;i < myVector->n;i++ ) { 537 unsortedVector->data.F32[ i ] = myVector->data.F32[ i ]; 538 } 539 } 540 } 541 541 // Sort the temporary vectors. 542 542 psVectorSort( sortedVector, unsortedVector ); 543 543 544 544 // Calculate the median exactly. 545 545 // XXX: Is this the correct action? 546 546 if ( 0 == ( nValues % 2 ) ) { 547 stats->sampleMedian = 0.5 * ( sortedVector->data.F32[ ( nValues / 2 ) - 1 ] +548 sortedVector->data.F32[ nValues / 2 ] );549 } else {550 stats->sampleMedian = sortedVector->data.F32[ nValues / 2 ];551 }552 547 stats->sampleMedian = 0.5 * ( sortedVector->data.F32[ ( nValues / 2 ) - 1 ] + 548 sortedVector->data.F32[ nValues / 2 ] ); 549 } else { 550 stats->sampleMedian = sortedVector->data.F32[ nValues / 2 ]; 551 } 552 553 553 // Free the temporary data structures. 554 554 psFree( unsortedVector ); … … 577 577 float gaussianCoefs[ 1 + ( 2 * GAUSS_WIDTH ) ]; // The Gaussian Coefficients 578 578 psVector *smooth = psVectorAlloc( robustHistogram->nums->n, PS_TYPE_F32 ); 579 579 580 580 for ( i = 0;i < ( 1 + ( 2 * GAUSS_WIDTH ) );i++ ) { 581 if ( fabs( sigma ) >= FLT_EPSILON ) {582 // If sigma does not equal zero, then we use Gaussian smoothing.583 #ifdef DARWIN584 denom = ( float ) sqrt( 2.0 * M_PI * sigma * sigma );585 #else586 587 denom = sqrtf( 2.0 * M_PI * sigma * sigma );588 #endif589 590 expo = - ( float ) ( ( i - GAUSS_WIDTH ) * ( i - GAUSS_WIDTH ) );591 expo /= ( 2.0 * sigma * sigma );592 gaussianCoefs[ i ] = exp( expo / denom );593 594 // NOTE: Gaussian smoothing just isn't working with low sigma595 // values. The problem is that the Gaussian coefficients are596 // all zero, except for the middle coefficient, which is exactly597 // one. Therefore, I'm using boxcar smoothing.598 gaussianCoefs[ i ] = 1.0 / ( 1.0 + ( 2.0 * ( float ) GAUSS_WIDTH ) );599 // printf("gaussianCoefs[%d] is %f\n", i, gaussianCoefs[i]);600 } else {601 /* If sigma equals zero (all pixels have the same value)602 * the above code will divide by zero. Therefore, we don't need603 * to smooth the data.604 */605 for ( i = 0;i < robustHistogram->nums->n;i++ ) {606 smooth->data.F32[ i ] = ( float ) robustHistogram->nums->data.S32[ i ];607 }608 return ( smooth );609 }610 }611 581 if ( fabs( sigma ) >= FLT_EPSILON ) { 582 // If sigma does not equal zero, then we use Gaussian smoothing. 583 #ifdef DARWIN 584 denom = ( float ) sqrt( 2.0 * M_PI * sigma * sigma ); 585 #else 586 587 denom = sqrtf( 2.0 * M_PI * sigma * sigma ); 588 #endif 589 590 expo = - ( float ) ( ( i - GAUSS_WIDTH ) * ( i - GAUSS_WIDTH ) ); 591 expo /= ( 2.0 * sigma * sigma ); 592 gaussianCoefs[ i ] = exp( expo / denom ); 593 594 // NOTE: Gaussian smoothing just isn't working with low sigma 595 // values. The problem is that the Gaussian coefficients are 596 // all zero, except for the middle coefficient, which is exactly 597 // one. Therefore, I'm using boxcar smoothing. 598 gaussianCoefs[ i ] = 1.0 / ( 1.0 + ( 2.0 * ( float ) GAUSS_WIDTH ) ); 599 // printf("gaussianCoefs[%d] is %f\n", i, gaussianCoefs[i]); 600 } else { 601 /* If sigma equals zero (all pixels have the same value) 602 * the above code will divide by zero. Therefore, we don't need 603 * to smooth the data. 604 */ 605 for ( i = 0;i < robustHistogram->nums->n;i++ ) { 606 smooth->data.F32[ i ] = ( float ) robustHistogram->nums->data.S32[ i ]; 607 } 608 return ( smooth ); 609 } 610 } 611 612 612 // Perform the actual smoothing. 613 613 for ( i = 0;i < robustHistogram->nums->n;i++ ) { 614 smooth->data.F32[ i ] = 0.0;615 for ( j = -GAUSS_WIDTH;j <= + GAUSS_WIDTH;j++ ) {616 if ( ( ( j + i ) >= 0 ) && ( ( j + i ) < smooth->n ) ) {617 smooth->data.F32[ i ] += ( gaussianCoefs[ j + GAUSS_WIDTH ] *618 ( float ) robustHistogram->nums->data.S32[ j + i ] );619 }620 }621 }614 smooth->data.F32[ i ] = 0.0; 615 for ( j = -GAUSS_WIDTH;j <= + GAUSS_WIDTH;j++ ) { 616 if ( ( ( j + i ) >= 0 ) && ( ( j + i ) < smooth->n ) ) { 617 smooth->data.F32[ i ] += ( gaussianCoefs[ j + GAUSS_WIDTH ] * 618 ( float ) robustHistogram->nums->data.S32[ j + i ] ); 619 } 620 } 621 } 622 622 return ( smooth ); 623 623 } … … 646 646 float rangeMin = 0.0; // Exclude data below this 647 647 float rangeMax = 0.0; // Exclude date above this 648 648 649 649 // Determine how many data points fit inside this min/max range 650 650 // and are not maxed, IF the maskVector is not NULL> 651 651 nValues = p_psVectorNValues( myVector, maskVector, maskVal, stats ); 652 652 653 653 // Allocate temporary vectors for the data. 654 654 unsortedVector = psVectorAlloc( nValues, PS_TYPE_F32 ); … … 656 656 sortedVector = psVectorAlloc( nValues, PS_TYPE_F32 ); 657 657 sortedVector->n = sortedVector->nalloc; 658 658 659 659 // Determine if we must only use data points within a min/max range. 660 660 if ( stats->options & PS_STAT_USE_RANGE ) { 661 rangeMin = stats->min; 662 rangeMax = stats->max; 663 // Store all non-masked data points within the min/max range 664 // into the temporary vectors. 665 count = 0; 666 if ( maskVector != NULL ) { 667 for ( i = 0;i < myVector->n;i++ ) { 668 if ( !( maskVal & maskVector->data.U8[ i ] ) && 669 ( rangeMin <= myVector->data.F32[ i ] ) && 670 ( myVector->data.F32[ i ] <= rangeMax ) ) { 671 unsortedVector->data.F32[ count++ ] = myVector->data.F32[ i ]; 672 } 673 } 674 } else { 675 for ( i = 0;i < myVector->n;i++ ) { 676 if ( ( rangeMin <= myVector->data.F32[ i ] ) && 677 ( myVector->data.F32[ i ] <= rangeMax ) ) { 678 unsortedVector->data.F32[ count++ ] = myVector->data.F32[ i ]; 679 } 680 } 681 } 661 rangeMin = stats->min; 662 rangeMax = stats->max; 663 // Store all non-masked data points within the min/max range 664 // into the temporary vectors. 665 count = 0; 666 if ( maskVector != NULL ) { 667 for ( i = 0;i < myVector->n;i++ ) { 668 if ( !( maskVal & maskVector->data.U8[ i ] ) && 669 ( rangeMin <= myVector->data.F32[ i ] ) && 670 ( myVector->data.F32[ i ] <= rangeMax ) ) { 671 unsortedVector->data.F32[ count++ ] = myVector->data.F32[ i ]; 672 } 673 } 682 674 } else { 683 // Store all non-masked data points into the temporary vectors. 684 count = 0; 685 if ( maskVector != NULL ) { 686 for ( i = 0;i < myVector->n;i++ ) { 687 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 688 unsortedVector->data.F32[ count++ ] = myVector->data.F32[ i ]; 689 } 690 } 691 } else { 692 for ( i = 0;i < myVector->n;i++ ) { 693 unsortedVector->data.F32[ i ] = myVector->data.F32[ i ]; 694 } 695 } 696 } 697 675 for ( i = 0;i < myVector->n;i++ ) { 676 if ( ( rangeMin <= myVector->data.F32[ i ] ) && 677 ( myVector->data.F32[ i ] <= rangeMax ) ) { 678 unsortedVector->data.F32[ count++ ] = myVector->data.F32[ i ]; 679 } 680 } 681 } 682 } else { 683 // Store all non-masked data points into the temporary vectors. 684 count = 0; 685 if ( maskVector != NULL ) { 686 for ( i = 0;i < myVector->n;i++ ) { 687 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 688 unsortedVector->data.F32[ count++ ] = myVector->data.F32[ i ]; 689 } 690 } 691 } else { 692 for ( i = 0;i < myVector->n;i++ ) { 693 unsortedVector->data.F32[ i ] = myVector->data.F32[ i ]; 694 } 695 } 696 } 697 698 698 // Sort the temporary vectors. 699 699 psVectorSort( sortedVector, unsortedVector ); 700 700 701 701 // Calculate the quartile points exactly. 702 702 stats->sampleUQ = sortedVector->data.F32[ 3 * ( nValues / 4 ) ]; 703 703 stats->sampleLQ = sortedVector->data.F32[ nValues / 4 ]; 704 704 705 705 // Free the temporary data structures. 706 706 psFree( unsortedVector ); … … 735 735 float rangeMin = 0.0; // Exclude data below this 736 736 float rangeMax = 0.0; // Exclude date above this 737 737 738 738 // This procedure requires the mean. If it has not been already 739 739 // calculated, then call p_psVectorSampleMean() 740 740 if ( 0 != isnan( stats->sampleMean ) ) { 741 p_psVectorSampleMean( myVector, maskVector, maskVal, stats );742 }741 p_psVectorSampleMean( myVector, maskVector, maskVal, stats ); 742 } 743 743 mean = stats->sampleMean; 744 744 745 745 if ( stats->options & PS_STAT_USE_RANGE ) { 746 if ( maskVector != NULL ) { 747 for ( i = 0;i < myVector->n;i++ ) { 748 if ( !( maskVal & maskVector->data.U8[ i ] ) && 749 ( rangeMin <= myVector->data.F32[ i ] ) && 750 ( myVector->data.F32[ i ] <= rangeMax ) ) { 751 diff = myVector->data.F32[ i ] - mean; 752 sumSquares += ( diff * diff ); 753 sumDiffs += diff; 754 countInt++; 755 } 756 } 757 } else { 758 for ( i = 0;i < myVector->n;i++ ) { 759 if ( ( rangeMin <= myVector->data.F32[ i ] ) && 760 ( myVector->data.F32[ i ] <= rangeMax ) ) { 761 diff = myVector->data.F32[ i ] - mean; 762 sumSquares += ( diff * diff ); 763 sumDiffs += diff; 764 countInt++; 765 } 766 } 767 countInt = myVector->n; 768 } 746 if ( maskVector != NULL ) { 747 for ( i = 0;i < myVector->n;i++ ) { 748 if ( !( maskVal & maskVector->data.U8[ i ] ) && 749 ( rangeMin <= myVector->data.F32[ i ] ) && 750 ( myVector->data.F32[ i ] <= rangeMax ) ) { 751 diff = myVector->data.F32[ i ] - mean; 752 sumSquares += ( diff * diff ); 753 sumDiffs += diff; 754 countInt++; 755 } 756 } 769 757 } else { 770 if ( maskVector != NULL ) { 771 for ( i = 0;i < myVector->n;i++ ) { 772 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 773 diff = myVector->data.F32[ i ] - mean; 774 sumSquares += ( diff * diff ); 775 sumDiffs += diff; 776 countInt++; 777 } 778 } 779 } else { 780 for ( i = 0;i < myVector->n;i++ ) { 781 diff = myVector->data.F32[ i ] - mean; 782 sumSquares += ( diff * diff ); 783 sumDiffs += diff; 784 countInt++; 785 } 786 countInt = myVector->n; 787 } 788 } 758 for ( i = 0;i < myVector->n;i++ ) { 759 if ( ( rangeMin <= myVector->data.F32[ i ] ) && 760 ( myVector->data.F32[ i ] <= rangeMax ) ) { 761 diff = myVector->data.F32[ i ] - mean; 762 sumSquares += ( diff * diff ); 763 sumDiffs += diff; 764 countInt++; 765 } 766 } 767 countInt = myVector->n; 768 } 769 } else { 770 if ( maskVector != NULL ) { 771 for ( i = 0;i < myVector->n;i++ ) { 772 if ( !( maskVal & maskVector->data.U8[ i ] ) ) { 773 diff = myVector->data.F32[ i ] - mean; 774 sumSquares += ( diff * diff ); 775 sumDiffs += diff; 776 countInt++; 777 } 778 } 779 } else { 780 for ( i = 0;i < myVector->n;i++ ) { 781 diff = myVector->data.F32[ i ] - mean; 782 sumSquares += ( diff * diff ); 783 sumDiffs += diff; 784 countInt++; 785 } 786 countInt = myVector->n; 787 } 788 } 789 789 countFloat = ( float ) countInt; 790 790 791 791 #ifdef DARWIN 792 792 793 793 stats->sampleStdev = ( float ) sqrt( ( sumSquares - ( sumDiffs * 794 794 sumDiffs / countFloat ) ) / ( countFloat - 1 ) ); 795 795 #else 796 796 797 797 stats->sampleStdev = sqrtf( ( sumSquares - ( sumDiffs * 798 798 sumDiffs / countFloat ) ) / ( countFloat - 1 ) ); … … 824 824 float oldStanStdev = 0.0; // Temporary variable 825 825 psVector *tmpMask = NULL; // Temporary vector 826 826 827 827 // Endure that stats->clipIter is within the proper range. 828 828 if ( !( ( CLIPPED_NUM_ITER_LB <= stats->clipIter ) && 829 829 ( stats->clipIter <= CLIPPED_NUM_ITER_UB ) ) ) { 830 psAbort( __func__, "Unallowed value for clipIter (%d).\n",831 stats->clipIter );832 }833 830 psAbort( __func__, "Unallowed value for clipIter (%d).\n", 831 stats->clipIter ); 832 } 833 834 834 // Endure that stats->clipSigma is within the proper range. 835 835 if ( !( ( CLIPPED_SIGMA_LB <= stats->clipSigma ) && 836 836 ( stats->clipSigma <= CLIPPED_SIGMA_UB ) ) ) { 837 psAbort( __func__, "Unallowed value for clipSigma (%f).\n",838 stats->clipSigma );839 }840 837 psAbort( __func__, "Unallowed value for clipSigma (%f).\n", 838 stats->clipSigma ); 839 } 840 841 841 // We allocate a temporary mask vector since during the iterative 842 842 // steps that follow, we will be masking off additional data points. … … 844 844 tmpMask = psVectorAlloc( myVector->n, PS_TYPE_U8 ); 845 845 tmpMask->n = myVector->n; 846 846 847 847 // If we were called with a mask vector, then initialize the temporary 848 848 // mask vector with those values. 849 849 if ( maskVector != NULL ) { 850 for ( i = 0;i < tmpMask->n;i++ ) {851 tmpMask->data.U8[ i ] = maskVector->data.U8[ i ];852 }853 }854 850 for ( i = 0;i < tmpMask->n;i++ ) { 851 tmpMask->data.U8[ i ] = maskVector->data.U8[ i ]; 852 } 853 } 854 855 855 // 1. Compute the sample median. 856 856 // NOTE: This seems odd. Verify with IfA that we want to calculate the 857 857 // median here, not the mean. 858 858 p_psVectorSampleMedian( myVector, maskVector, maskVal, stats ); 859 859 860 860 // 2. Compute the sample standard deviation. 861 861 p_psVectorSampleStdev( myVector, maskVector, maskVal, stats ); 862 862 863 863 // 3. Use the sample median as the first estimator of the mean X. 864 864 clippedMean = stats->sampleMean; 865 865 866 866 // 4. Use the sample stdev as the first estimator of the mean stdev. 867 867 clippedStdev = stats->sampleStdev; 868 868 869 869 // Must save the old sampleMean and sampleStdev since the following code 870 870 // block overwrites them. 871 871 oldStanMean = stats->sampleMean; 872 872 oldStanStdev = stats->sampleStdev; 873 873 874 874 // 5. Repeat N times: 875 875 for ( i = 0;i < stats->clipIter;i++ ) { 876 for ( j = 0;j < myVector->n;j++ ) {877 // a) Exclude all values x_i for which |x_i - x| > K * stdev878 if ( fabs( myVector->data.F32[ j ] - clippedMean ) >879 ( stats->clipSigma * clippedStdev ) ) {880 tmpMask->data.U8[ i ] = 0xff;881 }882 // b) compute new mean and stdev883 p_psVectorSampleMedian( myVector, tmpMask, maskVal, stats );884 p_psVectorSampleStdev( myVector, tmpMask, maskVal, stats );885 886 // c) Use the new mean for x887 clippedMean = stats->sampleMean;888 889 // d) Use the new stdev for stdev890 clippedStdev = stats->sampleStdev;891 }892 893 }876 for ( j = 0;j < myVector->n;j++ ) { 877 // a) Exclude all values x_i for which |x_i - x| > K * stdev 878 if ( fabs( myVector->data.F32[ j ] - clippedMean ) > 879 ( stats->clipSigma * clippedStdev ) ) { 880 tmpMask->data.U8[ i ] = 0xff; 881 } 882 // b) compute new mean and stdev 883 p_psVectorSampleMedian( myVector, tmpMask, maskVal, stats ); 884 p_psVectorSampleStdev( myVector, tmpMask, maskVal, stats ); 885 886 // c) Use the new mean for x 887 clippedMean = stats->sampleMean; 888 889 // d) Use the new stdev for stdev 890 clippedStdev = stats->sampleStdev; 891 } 892 893 } 894 894 stats->sampleMean = oldStanMean; 895 895 stats->sampleStdev = oldStanStdev; 896 896 897 897 // 7. The last calcuated value of x is the cliped mean. 898 898 if ( stats->options & PS_STAT_CLIPPED_MEAN ) { 899 stats->clippedMean = clippedMean;900 }901 899 stats->clippedMean = clippedMean; 900 } 901 902 902 // 8. The last calcuated value of stdev is the cliped stdev. 903 903 if ( stats->options & PS_STAT_CLIPPED_STDEV ) { 904 stats->clippedStdev = clippedStdev;905 }906 904 stats->clippedStdev = clippedStdev; 905 } 906 907 907 psFree( tmpMask ); 908 908 } … … 918 918 float range = 0.0; 919 919 int i = 0; 920 920 921 921 for ( i = 0;i < myData->n;i++ ) { 922 if ( myData->data.F32[ i ] < min ) {923 min = myData->data.F32[ i ];924 }925 if ( myData->data.F32[ i ] > max ) {926 max = myData->data.F32[ i ];927 }928 }929 922 if ( myData->data.F32[ i ] < min ) { 923 min = myData->data.F32[ i ]; 924 } 925 if ( myData->data.F32[ i ] > max ) { 926 max = myData->data.F32[ i ]; 927 } 928 } 929 930 930 range = max - min; 931 931 for ( i = 0;i < myData->n;i++ ) { 932 myData->data.F32[ i ] = ( myData->data.F32[ i ] - min ) / range;933 }932 myData->data.F32[ i ] = ( myData->data.F32[ i ] - min ) / range; 933 } 934 934 } 935 935 … … 948 948 float tmp = exp( -( ( x - mean ) * ( x - mean ) ) / ( 2.0 * stdev * stdev ) ); 949 949 tmp /= ( ( float ) sqrt( 2.0 * M_PI * ( stdev * stdev ) ) ); 950 950 951 951 // printf("p_psGaussian((%.2f), %.2f, %.2f) is %.2f\n", x, mean, stdev, tmp); 952 952 return ( tmp ); … … 965 965 float stdev = myParams->data.F32[ 1 ]; 966 966 float tmp = 0.0; 967 967 968 968 if ( whichParam == 0 ) { 969 // Return the derivative w.r.t. the mean. 970 tmp = ( x - mean ) * p_psGaussian( myData, myParams ); 971 tmp /= ( stdev * stdev ); 972 } else if ( whichParam == 1 ) { 969 // Return the derivative w.r.t. the mean. 970 tmp = ( x - mean ) * p_psGaussian( myData, myParams ); 971 tmp /= ( stdev * stdev ); 972 } else 973 if ( whichParam == 1 ) { 973 974 // Return the derivative w.r.t. the stdev. 974 975 tmp = ( x - mean ) * ( x - mean ) * p_psGaussian( myData, myParams ); … … 976 977 } 977 978 printf( "p_psGaussianDeriv((%.2f), %.2f, %.2f, (%d)) is %.2f\n", x, mean, stdev, whichParam, tmp ); 978 979 979 980 return ( tmp ); 980 981 } … … 994 995 float C = myParams->data.F32[ 2 ]; 995 996 float tmp = 0.0; 996 997 997 998 tmp = ( A * x * x ) + ( B * x ) + C; 998 999 return ( tmp ); … … 1009 1010 float x = myCoords->data.F32[ 0 ]; 1010 1011 float tmp = 0.0; 1011 1012 1012 1013 if ( whichParamDeriv == 0 ) { 1013 tmp = x * x; 1014 } else if ( whichParamDeriv == 1 ) { 1014 tmp = x * x; 1015 } else 1016 if ( whichParamDeriv == 1 ) { 1015 1017 tmp = x; 1016 } else if ( whichParamDeriv == 2 ) { 1017 tmp = 1.0; 1018 } 1019 1018 } else 1019 if ( whichParamDeriv == 2 ) { 1020 tmp = 1.0; 1021 } 1022 1020 1023 return ( tmp ); 1021 1024 } … … 1039 1042 float oldMidpoint = 1.0; 1040 1043 float f = 0.0; 1041 1044 1042 1045 // printf("p_ps1DPolyMedian(%f, %f, %f) \n", rangeLow, rangeHigh, getThisValue); 1043 1046 1044 1047 while ( numIterations < MAX_ITERATIONS ) { 1045 midpoint = ( rangeHigh + rangeLow ) / 2.0;1046 if ( fabs( midpoint - oldMidpoint ) <= FLT_EPSILON ) {1047 return ( midpoint );1048 }1049 oldMidpoint = midpoint;1050 1051 f = psPolynomial1DEval( midpoint, myPoly );1052 // printf("p_ps1DPolyMedian() iteration %d. f(%f) is %f\n", numIterations, midpoint, f);1053 if ( fabs( f - getThisValue ) <= FLT_EPSILON ) {1054 return ( midpoint );1055 }1056 1057 if ( f > getThisValue ) {1058 rangeHigh = midpoint;1059 } else {1060 rangeLow = midpoint;1061 }1062 numIterations++;1063 }1048 midpoint = ( rangeHigh + rangeLow ) / 2.0; 1049 if ( fabs( midpoint - oldMidpoint ) <= FLT_EPSILON ) { 1050 return ( midpoint ); 1051 } 1052 oldMidpoint = midpoint; 1053 1054 f = psPolynomial1DEval( midpoint, myPoly ); 1055 // printf("p_ps1DPolyMedian() iteration %d. f(%f) is %f\n", numIterations, midpoint, f); 1056 if ( fabs( f - getThisValue ) <= FLT_EPSILON ) { 1057 return ( midpoint ); 1058 } 1059 1060 if ( f > getThisValue ) { 1061 rangeHigh = midpoint; 1062 } else { 1063 rangeLow = midpoint; 1064 } 1065 numIterations++; 1066 } 1064 1067 return ( midpoint ); 1065 1068 } … … 1082 1085 psVector *yErr = psVectorAlloc( 3, PS_TYPE_F64 ); 1083 1086 psPolynomial1D *myPoly = psPolynomial1DAlloc( 2 ); 1084 1087 1085 1088 if ( ( binNum > 0 ) && 1086 1089 ( binNum < ( histogram->nums->n + 1 ) ) ) { 1087 x->data.F64[ 0 ] = ( double ) 0.5 *1088 ( histogram->bounds->data.F32[ binNum - 1 ] +1089 histogram->bounds->data.F32[ binNum ] );1090 x->data.F64[ 1 ] = ( double ) 0.5 *1091 ( histogram->bounds->data.F32[ binNum ] +1092 histogram->bounds->data.F32[ binNum + 1 ] );1093 x->data.F64[ 2 ] = ( double ) 0.5 *1094 ( histogram->bounds->data.F32[ binNum + 1 ] +1095 histogram->bounds->data.F32[ binNum + 2 ] );1096 1097 y->data.F64[ 0 ] = cumulativeSums->data.F32[ binNum - 1 ];1098 y->data.F64[ 1 ] = cumulativeSums->data.F32[ binNum ];1099 y->data.F64[ 2 ] = cumulativeSums->data.F32[ binNum + 1 ];1100 1101 if ( !( ( y->data.F64[ 0 ] <= fitFloat ) &&1102 ( fitFloat <= y->data.F64[ 2 ] ) ) ) {1103 psAbort( __func__, "p_psVectorRobustStats(0): midpoint not within y-range\n" );1104 }1105 1106 yErr->data.F64[ 0 ] = 1.0;1107 yErr->data.F64[ 1 ] = 1.0;1108 yErr->data.F64[ 2 ] = 1.0;1109 1110 myPoly = psVectorFitPolynomial1D( myPoly, x, y, yErr );1111 return ( p_ps1DPolyMedian( myPoly, x->data.F64[ 0 ], x->data.F64[ 2 ],1112 fitFloat ) );1113 } else {1114 return ( 0.5 * ( histogram->bounds->data.F32[ binNum + 1 ] +1115 histogram->bounds->data.F32[ binNum ] ) );1116 }1117 1090 x->data.F64[ 0 ] = ( double ) 0.5 * 1091 ( histogram->bounds->data.F32[ binNum - 1 ] + 1092 histogram->bounds->data.F32[ binNum ] ); 1093 x->data.F64[ 1 ] = ( double ) 0.5 * 1094 ( histogram->bounds->data.F32[ binNum ] + 1095 histogram->bounds->data.F32[ binNum + 1 ] ); 1096 x->data.F64[ 2 ] = ( double ) 0.5 * 1097 ( histogram->bounds->data.F32[ binNum + 1 ] + 1098 histogram->bounds->data.F32[ binNum + 2 ] ); 1099 1100 y->data.F64[ 0 ] = cumulativeSums->data.F32[ binNum - 1 ]; 1101 y->data.F64[ 1 ] = cumulativeSums->data.F32[ binNum ]; 1102 y->data.F64[ 2 ] = cumulativeSums->data.F32[ binNum + 1 ]; 1103 1104 if ( !( ( y->data.F64[ 0 ] <= fitFloat ) && 1105 ( fitFloat <= y->data.F64[ 2 ] ) ) ) { 1106 psAbort( __func__, "p_psVectorRobustStats(0): midpoint not within y-range\n" ); 1107 } 1108 1109 yErr->data.F64[ 0 ] = 1.0; 1110 yErr->data.F64[ 1 ] = 1.0; 1111 yErr->data.F64[ 2 ] = 1.0; 1112 1113 myPoly = psVectorFitPolynomial1D( myPoly, x, y, yErr ); 1114 return ( p_ps1DPolyMedian( myPoly, x->data.F64[ 0 ], x->data.F64[ 2 ], 1115 fitFloat ) ); 1116 } else { 1117 return ( 0.5 * ( histogram->bounds->data.F32[ binNum + 1 ] + 1118 histogram->bounds->data.F32[ binNum ] ) ); 1119 } 1120 1118 1121 psFree( x ); 1119 1122 psFree( y ); … … 1187 1190 float sumNfit = 0.0; 1188 1191 float cumulativeMedian = 0.0; 1189 1192 1190 1193 // Compute the initial bin size of the robust histogram. This is done 1191 1194 // by computing the clipped standard deviation of the vector, and dividing … … 1193 1196 p_psVectorClippedStats( myVector, maskVector, maskVal, tmpStats ); 1194 1197 binSize = tmpStats->clippedStdev / 10.0f; 1195 1198 1196 1199 // If stats->clippedStdev == 0.0, then all data elements have the same 1197 1200 // value. Therefore, we can set the appropiate results and return. 1198 1201 if ( fabs( binSize ) <= FLT_EPSILON ) { 1199 if ( stats->options & PS_STAT_ROBUST_MEAN ) {1200 stats->robustMean = stats->clippedMean;1201 }1202 if ( stats->options & PS_STAT_ROBUST_MEDIAN ) {1203 stats->robustMedian = stats->clippedMean;1204 }1205 if ( stats->options & PS_STAT_ROBUST_MODE ) {1206 stats->robustMode = stats->clippedMean;1207 }1208 if ( stats->options & PS_STAT_ROBUST_STDEV ) {1209 stats->robustStdev = 0.0;1210 }1211 if ( stats->options & PS_STAT_ROBUST_QUARTILE ) {1212 stats->robustUQ = stats->clippedMean;1213 stats->robustLQ = stats->clippedMean;1214 }1215 // XXX: Set these to the number of unmasked data points?1216 stats->robustNfit = 0.0;1217 stats->robustN50 = 0.0;1218 psFree( tmpStats );1219 return ;1220 }1221 1202 if ( stats->options & PS_STAT_ROBUST_MEAN ) { 1203 stats->robustMean = stats->clippedMean; 1204 } 1205 if ( stats->options & PS_STAT_ROBUST_MEDIAN ) { 1206 stats->robustMedian = stats->clippedMean; 1207 } 1208 if ( stats->options & PS_STAT_ROBUST_MODE ) { 1209 stats->robustMode = stats->clippedMean; 1210 } 1211 if ( stats->options & PS_STAT_ROBUST_STDEV ) { 1212 stats->robustStdev = 0.0; 1213 } 1214 if ( stats->options & PS_STAT_ROBUST_QUARTILE ) { 1215 stats->robustUQ = stats->clippedMean; 1216 stats->robustLQ = stats->clippedMean; 1217 } 1218 // XXX: Set these to the number of unmasked data points? 1219 stats->robustNfit = 0.0; 1220 stats->robustN50 = 0.0; 1221 psFree( tmpStats ); 1222 return ; 1223 } 1224 1222 1225 // Determine minimum and maximum values in the data vector. 1223 1226 if ( isnan( stats->min ) ) { 1224 p_psVectorMin( myVector, maskVector, maskVal, stats );1225 }1227 p_psVectorMin( myVector, maskVector, maskVal, stats ); 1228 } 1226 1229 if ( isnan( stats->max ) ) { 1227 p_psVectorMax( myVector, maskVector, maskVal, stats );1228 }1229 1230 p_psVectorMax( myVector, maskVector, maskVal, stats ); 1231 } 1232 1230 1233 // Create the histogram structure. NOTE: we can not specify the bin size 1231 1234 // precisely since the argument to psHistogramAlloc() is the number of … … 1236 1239 stats->max, 1237 1240 numBins ); 1238 1241 1239 1242 // Populate the histogram array. 1240 1243 psVectorHistogram( robustHistogram, myVector, maskVector, maskVal ); 1241 1244 1242 1245 // Smooth the histogram. 1243 1246 // XXX: is that the right stdev? 1244 1247 robustHistogramVector = p_psVectorsmoothHistGaussian( robustHistogram, 1245 1248 tmpStats->clippedStdev / 4.0f ); 1246 1249 1247 1250 // The following was necessary to fit a gaussian to the data, since 1248 1251 // gaussian functions produce data between 0.0 and 1.0. 1249 1252 // p_psNormalizeVector(robustHistogramVector); 1250 1253 1251 1254 /************************************************************************** 1252 1255 Determine the lower/upper quartiles. 1253 **************************************************************************/ 1256 **************************************************************************/ 1254 1257 // We define a vector called "cumulativeRobustSums..." where the value at 1255 1258 // index position i is equal to the sum of bins 0:i. This will be used … … 1258 1261 cumulativeRobustSumsFullRange->data.F32[ 0 ] = robustHistogramVector->data.F32[ 0 ]; 1259 1262 for ( i = 1;i < robustHistogramVector->n;i++ ) { 1260 cumulativeRobustSumsFullRange->data.F32[ i ] =1261 cumulativeRobustSumsFullRange->data.F32[ i - 1 ] +1262 robustHistogramVector->data.F32[ i ];1263 }1263 cumulativeRobustSumsFullRange->data.F32[ i ] = 1264 cumulativeRobustSumsFullRange->data.F32[ i - 1 ] + 1265 robustHistogramVector->data.F32[ i ]; 1266 } 1264 1267 sumRobust = cumulativeRobustSumsFullRange->data.F32[ robustHistogramVector->n - 1 ]; 1265 1268 1266 1269 // Determine the bin number containing the lower quartile point. 1267 1270 LQBinNum = -1; 1268 1271 for ( i = 0;i < cumulativeRobustSumsFullRange->n;i++ ) { 1269 if ( cumulativeRobustSumsFullRange->data.F32[ i ] >= ( sumRobust / 4.0 ) ) {1270 LQBinNum = i;1271 break;1272 }1273 }1274 1272 if ( cumulativeRobustSumsFullRange->data.F32[ i ] >= ( sumRobust / 4.0 ) ) { 1273 LQBinNum = i; 1274 break; 1275 } 1276 } 1277 1275 1278 // Determine the bin number containing the upper quartile point. 1276 1279 UQBinNum = -1; 1277 1280 for ( i = cumulativeRobustSumsFullRange->n - 1;i >= 0;i-- ) { 1278 if ( cumulativeRobustSumsFullRange->data.F32[ i ] <= ( 3.0 * sumRobust / 4.0 ) ) {1279 UQBinNum = i;1280 break;1281 }1282 }1283 1281 if ( cumulativeRobustSumsFullRange->data.F32[ i ] <= ( 3.0 * sumRobust / 4.0 ) ) { 1282 UQBinNum = i; 1283 break; 1284 } 1285 } 1286 1284 1287 if ( ( LQBinNum == -1 ) || 1285 1288 ( UQBinNum == -1 ) ) { 1286 psAbort( __func__, "Could not determine the robust lower/upper quartiles." );1287 }1289 psAbort( __func__, "Could not determine the robust lower/upper quartiles." ); 1290 } 1288 1291 /************************************************************************** 1289 1292 Determine the mode in the range LQ:UQ. 1290 **************************************************************************/ 1293 **************************************************************************/ 1291 1294 // Determine the bin with the peak value in the range LQ to UQ. 1292 1295 maxBinNum = LQBinNum; … … 1294 1297 sumN50 = ( float ) robustHistogram->nums->data.S32[ LQBinNum ]; 1295 1298 for ( i = LQBinNum + 1;i <= UQBinNum;i++ ) { 1296 if ( robustHistogramVector->data.F32[ i ] > maxBinCount ) {1297 maxBinNum = i;1298 maxBinCount = robustHistogramVector->data.F32[ i ];1299 }1300 sumN50 += ( float ) robustHistogram->nums->data.S32[ i ];1301 }1302 1299 if ( robustHistogramVector->data.F32[ i ] > maxBinCount ) { 1300 maxBinNum = i; 1301 maxBinCount = robustHistogramVector->data.F32[ i ]; 1302 } 1303 sumN50 += ( float ) robustHistogram->nums->data.S32[ i ]; 1304 } 1305 1303 1306 // XXX: is dL defined as the value at the LQ/UQ, or the bin number? 1304 1307 dL = ( UQBinNum - LQBinNum ) / 4; 1305 1308 1306 1309 printf( "(LQBinNum, UQBinNum, maxBinNum) is (%d, %d, %d)\n", LQBinNum, UQBinNum, maxBinNum ); 1307 1310 1308 1311 /************************************************************************** 1309 1312 Determine the mean/stdev for the bins in the range mode-dL to mode+dL … … 1311 1314 cumulativeRobustSumsDlRange = psVectorAlloc( robustHistogramVector->n, PS_TYPE_F32 ); 1312 1315 for ( i = 0;i < robustHistogramVector->n;i++ ) { 1313 cumulativeRobustSumsDlRange->data.F32[ i ] = 0.0;1314 }1316 cumulativeRobustSumsDlRange->data.F32[ i ] = 0.0; 1317 } 1315 1318 sumNfit = 0.0; 1316 1319 cumulativeMedian = 0.0; 1317 1320 for ( i = maxBinNum - dL;i <= maxBinNum + dL;i++ ) { 1318 if ( ( 0 <= i ) && ( i < robustHistogramVector->n ) ) {1319 cumulativeRobustSumsDlRange->data.F32[ i ] =1320 cumulativeRobustSumsDlRange->data.F32[ i - 1 ] +1321 robustHistogramVector->data.F32[ i ];1322 cumulativeMedian += robustHistogramVector->data.F32[ i ];1323 sumNfit += ( float ) robustHistogram->nums->data.S32[ i ];1324 }1325 }1326 1321 if ( ( 0 <= i ) && ( i < robustHistogramVector->n ) ) { 1322 cumulativeRobustSumsDlRange->data.F32[ i ] = 1323 cumulativeRobustSumsDlRange->data.F32[ i - 1 ] + 1324 robustHistogramVector->data.F32[ i ]; 1325 cumulativeMedian += robustHistogramVector->data.F32[ i ]; 1326 sumNfit += ( float ) robustHistogram->nums->data.S32[ i ]; 1327 } 1328 } 1329 1327 1330 // Calculate the mean of the smoothed robust histogram in the range 1328 1331 // mode-dL to mode+dL. We use the midpoint of each bin as the mean for … … 1330 1333 myMean = 0.0; 1331 1334 for ( i = maxBinNum - dL;i <= maxBinNum + dL;i++ ) { 1332 if ( ( 0 <= i ) && ( i < robustHistogramVector->n ) ) {1333 myMean += ( robustHistogramVector->data.F32[ i ] ) * 0.5 *1334 ( robustHistogram->bounds->data.F32[ i + 1 ] +1335 robustHistogram->bounds->data.F32[ i ] );1336 countFloat += robustHistogramVector->data.F32[ i ];1337 }1338 }1335 if ( ( 0 <= i ) && ( i < robustHistogramVector->n ) ) { 1336 myMean += ( robustHistogramVector->data.F32[ i ] ) * 0.5 * 1337 ( robustHistogram->bounds->data.F32[ i + 1 ] + 1338 robustHistogram->bounds->data.F32[ i ] ); 1339 countFloat += robustHistogramVector->data.F32[ i ]; 1340 } 1341 } 1339 1342 myMean /= countFloat; 1340 1343 1341 1344 // Calculate the stdev of the smoothed robust histogram in the range 1342 1345 // mode-dL to mode+dL. We use the midpoint of each bin as the mean for 1343 1346 // that bin. 1344 1347 for ( i = maxBinNum - dL;i <= maxBinNum + dL;i++ ) { 1345 if ( ( 0 <= i ) && ( i < robustHistogramVector->n ) ) {1346 diff = ( 0.5 * ( robustHistogram->bounds->data.F32[ i + 1 ] +1347 robustHistogram->bounds->data.F32[ i ] ) ) - myMean;1348 sumSquares += diff * diff * robustHistogramVector->data.F32[ i ];1349 sumDiffs += diff * robustHistogramVector->data.F32[ i ];1350 }1351 }1348 if ( ( 0 <= i ) && ( i < robustHistogramVector->n ) ) { 1349 diff = ( 0.5 * ( robustHistogram->bounds->data.F32[ i + 1 ] + 1350 robustHistogram->bounds->data.F32[ i ] ) ) - myMean; 1351 sumSquares += diff * diff * robustHistogramVector->data.F32[ i ]; 1352 sumDiffs += diff * robustHistogramVector->data.F32[ i ]; 1353 } 1354 } 1352 1355 myStdev = sqrt( ( sumSquares - ( sumDiffs * sumDiffs / countFloat ) ) / ( countFloat - 1 ) ); 1353 1356 1354 1357 /************************************************************************** 1355 1358 Set the appropriate members in the output stats struct. 1356 1359 **************************************************************************/ 1357 1360 if ( stats->options & PS_STAT_ROBUST_MEAN ) { 1358 stats->robustMean = myMean;1359 }1360 1361 stats->robustMean = myMean; 1362 } 1363 1361 1364 if ( stats->options & PS_STAT_ROBUST_MODE ) { 1362 stats->robustMode = 0.5 *1363 ( robustHistogram->bounds->data.F32[ maxBinNum ] +1364 robustHistogram->bounds->data.F32[ maxBinNum + 1 ] );1365 }1366 1365 stats->robustMode = 0.5 * 1366 ( robustHistogram->bounds->data.F32[ maxBinNum ] + 1367 robustHistogram->bounds->data.F32[ maxBinNum + 1 ] ); 1368 } 1369 1367 1370 if ( stats->options & PS_STAT_ROBUST_STDEV ) { 1368 stats->robustStdev = myStdev;1369 }1370 1371 stats->robustStdev = myStdev; 1372 } 1373 1371 1374 // To determine the median (and later, the lower/upper quartile), we fit 1372 1375 // a quadratic to the three bins surrounding the bin containing the median. … … 1374 1377 // the cumulative number of data points in all bins up to, and including, 1375 1378 // this bin. We then solve the quadratic for 1376 1379 1377 1380 if ( stats->options & PS_STAT_ROBUST_MEDIAN ) { 1378 if ( ( maxBinNum > 0 ) && ( maxBinNum < ( robustHistogram->nums->n - 1 ) ) ) {1379 x->data.F64[ 0 ] = ( double ) 0.5 *1380 ( robustHistogram->bounds->data.F32[ maxBinNum - 1 ] +1381 robustHistogram->bounds->data.F32[ maxBinNum ] );1382 x->data.F64[ 1 ] = ( double ) 0.5 *1383 ( robustHistogram->bounds->data.F32[ maxBinNum ] +1384 robustHistogram->bounds->data.F32[ maxBinNum + 1 ] );1385 x->data.F64[ 2 ] = ( double ) 0.5 *1386 ( robustHistogram->bounds->data.F32[ maxBinNum + 1 ] +1387 robustHistogram->bounds->data.F32[ maxBinNum + 2 ] );1388 1389 y->data.F64[ 0 ] = cumulativeRobustSumsDlRange->data.F32[ maxBinNum - 1 ];1390 y->data.F64[ 1 ] = cumulativeRobustSumsDlRange->data.F32[ maxBinNum ];1391 y->data.F64[ 2 ] = cumulativeRobustSumsDlRange->data.F32[ maxBinNum + 1 ];1392 1393 // Ensure that cumulativeMedian/2 is actually within the range of the bins1394 // we are using.1395 cumulativeMedian *= 0.5;1396 if ( !( ( y->data.F64[ 0 ] <= cumulativeMedian ) &&1397 ( cumulativeMedian <= y->data.F64[ 2 ] ) ) ) {1398 printf( "((%f), %f, %f)\n", cumulativeMedian, y->data.F64[ 0 ], y->data.F64[ 2 ] );1399 psAbort( __func__, "p_psVectorRobustStats(1): midpoint not within y-range\n" );1400 }1401 // XXX: yErr is not currently used by psVectorFitPolynomial1D(). We1402 // may have to set this meaningfully later.1403 yErr->data.F64[ 0 ] = 1.0;1404 yErr->data.F64[ 1 ] = 1.0;1405 yErr->data.F64[ 2 ] = 1.0;1406 1407 // Determine the coefficients of the polynomial.1408 myPoly = psVectorFitPolynomial1D( myPoly, x, y, yErr );1409 // Call p_ps1DPolyMedian(), which does a binary search on the1410 // polynomial, looking for the value x such that1411 // f(x) = cumulativeMedian.1412 stats->robustMedian = p_ps1DPolyMedian( myPoly, x->data.F64[ 0 ],1413 x->data.F64[ 2 ], cumulativeMedian );1414 } else {1415 // If the mode is the first/last histogram bin, then simply use1416 // the midpoint of that bin.1417 stats->robustMedian = 0.5 * ( robustHistogram->bounds->data.F32[ maxBinNum + 1 ] +1418 robustHistogram->bounds->data.F32[ maxBinNum ] );1419 }1420 }1421 1381 if ( ( maxBinNum > 0 ) && ( maxBinNum < ( robustHistogram->nums->n - 1 ) ) ) { 1382 x->data.F64[ 0 ] = ( double ) 0.5 * 1383 ( robustHistogram->bounds->data.F32[ maxBinNum - 1 ] + 1384 robustHistogram->bounds->data.F32[ maxBinNum ] ); 1385 x->data.F64[ 1 ] = ( double ) 0.5 * 1386 ( robustHistogram->bounds->data.F32[ maxBinNum ] + 1387 robustHistogram->bounds->data.F32[ maxBinNum + 1 ] ); 1388 x->data.F64[ 2 ] = ( double ) 0.5 * 1389 ( robustHistogram->bounds->data.F32[ maxBinNum + 1 ] + 1390 robustHistogram->bounds->data.F32[ maxBinNum + 2 ] ); 1391 1392 y->data.F64[ 0 ] = cumulativeRobustSumsDlRange->data.F32[ maxBinNum - 1 ]; 1393 y->data.F64[ 1 ] = cumulativeRobustSumsDlRange->data.F32[ maxBinNum ]; 1394 y->data.F64[ 2 ] = cumulativeRobustSumsDlRange->data.F32[ maxBinNum + 1 ]; 1395 1396 // Ensure that cumulativeMedian/2 is actually within the range of the bins 1397 // we are using. 1398 cumulativeMedian *= 0.5; 1399 if ( !( ( y->data.F64[ 0 ] <= cumulativeMedian ) && 1400 ( cumulativeMedian <= y->data.F64[ 2 ] ) ) ) { 1401 printf( "((%f), %f, %f)\n", cumulativeMedian, y->data.F64[ 0 ], y->data.F64[ 2 ] ); 1402 psAbort( __func__, "p_psVectorRobustStats(1): midpoint not within y-range\n" ); 1403 } 1404 // XXX: yErr is not currently used by psVectorFitPolynomial1D(). We 1405 // may have to set this meaningfully later. 1406 yErr->data.F64[ 0 ] = 1.0; 1407 yErr->data.F64[ 1 ] = 1.0; 1408 yErr->data.F64[ 2 ] = 1.0; 1409 1410 // Determine the coefficients of the polynomial. 1411 myPoly = psVectorFitPolynomial1D( myPoly, x, y, yErr ); 1412 // Call p_ps1DPolyMedian(), which does a binary search on the 1413 // polynomial, looking for the value x such that 1414 // f(x) = cumulativeMedian. 1415 stats->robustMedian = p_ps1DPolyMedian( myPoly, x->data.F64[ 0 ], 1416 x->data.F64[ 2 ], cumulativeMedian ); 1417 } else { 1418 // If the mode is the first/last histogram bin, then simply use 1419 // the midpoint of that bin. 1420 stats->robustMedian = 0.5 * ( robustHistogram->bounds->data.F32[ maxBinNum + 1 ] + 1421 robustHistogram->bounds->data.F32[ maxBinNum ] ); 1422 } 1423 } 1424 1422 1425 // The lower/upper quartile calculations are very similar to the median 1423 1426 // calculations. We fit a quadratic to the array containing the … … 1426 1429 // 1427 1430 if ( stats->options & PS_STAT_ROBUST_QUARTILE ) { 1428 countFloat = cumulativeRobustSumsFullRange->data.F32[ robustHistogramVector->n - 1 ];1429 1430 if ( ( LQBinNum > 0 ) && ( LQBinNum < ( robustHistogram->nums->n - 1 ) ) ) {1431 x->data.F64[ 0 ] = ( double ) 0.5 *1432 ( robustHistogram->bounds->data.F32[ LQBinNum - 1 ] +1433 robustHistogram->bounds->data.F32[ LQBinNum ] );1434 x->data.F64[ 1 ] = ( double ) 0.5 *1435 ( robustHistogram->bounds->data.F32[ LQBinNum ] +1436 robustHistogram->bounds->data.F32[ LQBinNum + 1 ] );1437 x->data.F64[ 2 ] = ( double ) 0.5 *1438 ( robustHistogram->bounds->data.F32[ LQBinNum + 1 ] +1439 robustHistogram->bounds->data.F32[ LQBinNum + 2 ] );1440 1441 y->data.F64[ 0 ] = cumulativeRobustSumsFullRange->data.F32[ LQBinNum - 1 ];1442 y->data.F64[ 1 ] = cumulativeRobustSumsFullRange->data.F32[ LQBinNum ];1443 y->data.F64[ 2 ] = cumulativeRobustSumsFullRange->data.F32[ LQBinNum + 1 ];1444 1445 if ( !( ( y->data.F64[ 0 ] <= ( countFloat / 4.0 ) ) &&1446 ( ( countFloat / 4.0 ) <= y->data.F64[ 2 ] ) ) ) {1447 psAbort( __func__, "p_psVectorRobustStats(2): midpoint not within y-range\n" );1448 }1449 1450 yErr->data.F64[ 0 ] = 1.0;1451 yErr->data.F64[ 1 ] = 1.0;1452 yErr->data.F64[ 2 ] = 1.0;1453 1454 myPoly = psVectorFitPolynomial1D( myPoly, x, y, yErr );1455 stats->robustLQ = p_ps1DPolyMedian( myPoly,1456 x->data.F64[ 0 ],1457 x->data.F64[ 2 ],1458 countFloat / 4.0 );1459 1460 } else {1461 // If the LQ is the first/last histogram bin, then simply use1462 // the midpoint of that bin.1463 stats->robustLQ = 0.5 * ( robustHistogram->bounds->data.F32[ LQBinNum + 1 ] +1464 robustHistogram->bounds->data.F32[ LQBinNum ] );1465 }1466 1467 if ( ( UQBinNum > 0 ) && ( UQBinNum < ( robustHistogram->nums->n - 1 ) ) ) {1468 x->data.F64[ 0 ] = ( double ) 0.5 *1469 ( robustHistogram->bounds->data.F32[ UQBinNum - 1 ] +1470 robustHistogram->bounds->data.F32[ UQBinNum ] );1471 x->data.F64[ 1 ] = ( double ) 0.5 *1472 ( robustHistogram->bounds->data.F32[ UQBinNum ] +1473 robustHistogram->bounds->data.F32[ UQBinNum + 1 ] );1474 x->data.F64[ 2 ] = ( double ) 0.5 *1475 ( robustHistogram->bounds->data.F32[ UQBinNum + 1 ] +1476 robustHistogram->bounds->data.F32[ UQBinNum + 2 ] );1477 1478 y->data.F64[ 0 ] = cumulativeRobustSumsFullRange->data.F32[ UQBinNum - 1 ];1479 y->data.F64[ 1 ] = cumulativeRobustSumsFullRange->data.F32[ UQBinNum ];1480 y->data.F64[ 2 ] = cumulativeRobustSumsFullRange->data.F32[ UQBinNum + 1 ];1481 1482 if ( !( ( y->data.F64[ 0 ] <= ( 3.0 * countFloat / 4.0 ) ) &&1483 ( ( 3.0 * countFloat / 4.0 ) <= y->data.F64[ 2 ] ) ) ) {1484 psAbort( __func__, "p_psVectorRobustStats(3): midpoint not within y-range\n" );1485 }1486 1487 yErr->data.F64[ 0 ] = 1.0;1488 yErr->data.F64[ 1 ] = 1.0;1489 yErr->data.F64[ 2 ] = 1.0;1490 1491 myPoly = psVectorFitPolynomial1D( myPoly, x, y, yErr );1492 stats->robustUQ = p_ps1DPolyMedian( myPoly,1493 x->data.F64[ 0 ],1494 x->data.F64[ 2 ],1495 3.0 * countFloat / 4.0 );1496 } else {1497 // If the UQ is the first/last histogram bin, then simply use1498 // the midpoint of that bin.1499 stats->robustUQ = 0.5 * ( robustHistogram->bounds->data.F32[ UQBinNum + 1 ] +1500 robustHistogram->bounds->data.F32[ UQBinNum ] );1501 }1502 }1431 countFloat = cumulativeRobustSumsFullRange->data.F32[ robustHistogramVector->n - 1 ]; 1432 1433 if ( ( LQBinNum > 0 ) && ( LQBinNum < ( robustHistogram->nums->n - 1 ) ) ) { 1434 x->data.F64[ 0 ] = ( double ) 0.5 * 1435 ( robustHistogram->bounds->data.F32[ LQBinNum - 1 ] + 1436 robustHistogram->bounds->data.F32[ LQBinNum ] ); 1437 x->data.F64[ 1 ] = ( double ) 0.5 * 1438 ( robustHistogram->bounds->data.F32[ LQBinNum ] + 1439 robustHistogram->bounds->data.F32[ LQBinNum + 1 ] ); 1440 x->data.F64[ 2 ] = ( double ) 0.5 * 1441 ( robustHistogram->bounds->data.F32[ LQBinNum + 1 ] + 1442 robustHistogram->bounds->data.F32[ LQBinNum + 2 ] ); 1443 1444 y->data.F64[ 0 ] = cumulativeRobustSumsFullRange->data.F32[ LQBinNum - 1 ]; 1445 y->data.F64[ 1 ] = cumulativeRobustSumsFullRange->data.F32[ LQBinNum ]; 1446 y->data.F64[ 2 ] = cumulativeRobustSumsFullRange->data.F32[ LQBinNum + 1 ]; 1447 1448 if ( !( ( y->data.F64[ 0 ] <= ( countFloat / 4.0 ) ) && 1449 ( ( countFloat / 4.0 ) <= y->data.F64[ 2 ] ) ) ) { 1450 psAbort( __func__, "p_psVectorRobustStats(2): midpoint not within y-range\n" ); 1451 } 1452 1453 yErr->data.F64[ 0 ] = 1.0; 1454 yErr->data.F64[ 1 ] = 1.0; 1455 yErr->data.F64[ 2 ] = 1.0; 1456 1457 myPoly = psVectorFitPolynomial1D( myPoly, x, y, yErr ); 1458 stats->robustLQ = p_ps1DPolyMedian( myPoly, 1459 x->data.F64[ 0 ], 1460 x->data.F64[ 2 ], 1461 countFloat / 4.0 ); 1462 1463 } else { 1464 // If the LQ is the first/last histogram bin, then simply use 1465 // the midpoint of that bin. 1466 stats->robustLQ = 0.5 * ( robustHistogram->bounds->data.F32[ LQBinNum + 1 ] + 1467 robustHistogram->bounds->data.F32[ LQBinNum ] ); 1468 } 1469 1470 if ( ( UQBinNum > 0 ) && ( UQBinNum < ( robustHistogram->nums->n - 1 ) ) ) { 1471 x->data.F64[ 0 ] = ( double ) 0.5 * 1472 ( robustHistogram->bounds->data.F32[ UQBinNum - 1 ] + 1473 robustHistogram->bounds->data.F32[ UQBinNum ] ); 1474 x->data.F64[ 1 ] = ( double ) 0.5 * 1475 ( robustHistogram->bounds->data.F32[ UQBinNum ] + 1476 robustHistogram->bounds->data.F32[ UQBinNum + 1 ] ); 1477 x->data.F64[ 2 ] = ( double ) 0.5 * 1478 ( robustHistogram->bounds->data.F32[ UQBinNum + 1 ] + 1479 robustHistogram->bounds->data.F32[ UQBinNum + 2 ] ); 1480 1481 y->data.F64[ 0 ] = cumulativeRobustSumsFullRange->data.F32[ UQBinNum - 1 ]; 1482 y->data.F64[ 1 ] = cumulativeRobustSumsFullRange->data.F32[ UQBinNum ]; 1483 y->data.F64[ 2 ] = cumulativeRobustSumsFullRange->data.F32[ UQBinNum + 1 ]; 1484 1485 if ( !( ( y->data.F64[ 0 ] <= ( 3.0 * countFloat / 4.0 ) ) && 1486 ( ( 3.0 * countFloat / 4.0 ) <= y->data.F64[ 2 ] ) ) ) { 1487 psAbort( __func__, "p_psVectorRobustStats(3): midpoint not within y-range\n" ); 1488 } 1489 1490 yErr->data.F64[ 0 ] = 1.0; 1491 yErr->data.F64[ 1 ] = 1.0; 1492 yErr->data.F64[ 2 ] = 1.0; 1493 1494 myPoly = psVectorFitPolynomial1D( myPoly, x, y, yErr ); 1495 stats->robustUQ = p_ps1DPolyMedian( myPoly, 1496 x->data.F64[ 0 ], 1497 x->data.F64[ 2 ], 1498 3.0 * countFloat / 4.0 ); 1499 } else { 1500 // If the UQ is the first/last histogram bin, then simply use 1501 // the midpoint of that bin. 1502 stats->robustUQ = 0.5 * ( robustHistogram->bounds->data.F32[ UQBinNum + 1 ] + 1503 robustHistogram->bounds->data.F32[ UQBinNum ] ); 1504 } 1505 } 1503 1506 stats->robustNfit = sumNfit; 1504 1507 stats->robustN50 = sumN50; 1505 1508 1506 1509 psFree( x ); 1507 1510 psFree( y ); … … 1576 1579 { 1577 1580 psStats * newStruct = NULL; 1578 1581 1579 1582 newStruct = ( psStats * ) psAlloc( sizeof( psStats ) ); 1580 1583 newStruct->sampleMean = NAN; … … 1600 1603 newStruct->binsize = NAN; 1601 1604 newStruct->options = options; 1602 1605 1603 1606 return ( newStruct ); 1604 1607 } … … 1623 1626 psHistogram *newHist = NULL; // The new histogram structure 1624 1627 float binSize = 0.0; // The histogram bin size 1625 1628 1626 1629 // NOTE: Verify that this is the correct action. 1627 1630 if ( n == 0 ) { 1628 return ( NULL );1629 }1631 return ( NULL ); 1632 } 1630 1633 if ( n < 0 ) { 1631 psAbort( __func__, "psHistogramAlloc() called with bin size %d.\n", n );1632 }1633 1634 psAbort( __func__, "psHistogramAlloc() called with bin size %d.\n", n ); 1635 } 1636 1634 1637 // NOTE: Verify that this is the correct action. 1635 1638 if ( lower > upper ) { 1636 return ( NULL );1637 }1638 1639 return ( NULL ); 1640 } 1641 1639 1642 // Allocate memory for the new histogram structure. If there are N 1640 1643 // bins, then there are N+1 bounds to those bins. … … 1643 1646 newHist->bounds = psVectorAlloc( n + 1, PS_TYPE_F32 ); 1644 1647 newHist->bounds->n = newHist->bounds->nalloc; 1645 1648 1646 1649 // Calculate the bounds for each bin. 1647 1650 binSize = ( upper - lower ) / ( float ) n; … … 1650 1653 binSize += FLT_EPSILON; 1651 1654 for ( i = 0;i < n + 1;i++ ) { 1652 newHist->bounds->data.F32[ i ] = lower + ( binSize * ( float ) i );1653 }1654 1655 newHist->bounds->data.F32[ i ] = lower + ( binSize * ( float ) i ); 1656 } 1657 1655 1658 // Allocate the bins, and initialize them to zero. 1656 1659 newHist->nums = psVectorAlloc( n, PS_TYPE_U32 ); 1657 1660 newHist->nums->n = newHist->nums->nalloc; 1658 1661 for ( i = 0;i < newHist->nums->n;i++ ) { 1659 newHist->nums->data.U32[ i ] = 0;1660 }1661 1662 newHist->nums->data.U32[ i ] = 0; 1663 } 1664 1662 1665 // Initialize the other members. 1663 1666 newHist->minNum = 0; 1664 1667 newHist->maxNum = 0; 1665 1668 newHist->uniform = true; 1666 1669 1667 1670 return ( newHist ); 1668 1671 } … … 1681 1684 psHistogram * newHist = NULL; // The new histogram structure 1682 1685 int i; // Loop index variable 1683 1686 1684 1687 // NOTE: Verify that this is the correct action. 1685 1688 if ( bounds == NULL ) { 1686 // psAbort(__func__, "psHistogram requested with NULL bounds");1687 return ( NULL );1688 }1689 1689 // psAbort(__func__, "psHistogram requested with NULL bounds"); 1690 return ( NULL ); 1691 } 1692 1690 1693 // NOTE: Verify that this is the correct action. 1691 1694 if ( bounds->n <= 1 ) { 1692 // psAbort(__func__, "psHistogram requested with NULL bounds");1693 return ( NULL );1694 }1695 1695 // psAbort(__func__, "psHistogram requested with NULL bounds"); 1696 return ( NULL ); 1697 } 1698 1696 1699 if ( bounds->type.type != PS_TYPE_F32 ) { 1697 // psAbort(__func__, "psHistogram request a bound which is not type F32");1698 return ( NULL );1699 }1700 1700 // psAbort(__func__, "psHistogram request a bound which is not type F32"); 1701 return ( NULL ); 1702 } 1703 1701 1704 // Allocate memory for the new histogram structure. 1702 1705 newHist = ( psHistogram * ) psAlloc( sizeof( psHistogram ) ); … … 1705 1708 newHist->bounds->n = newHist->bounds->nalloc; 1706 1709 for ( i = 0;i < bounds->n;i++ ) { 1707 newHist->bounds->data.F32[ i ] = bounds->data.F32[ i ];1708 }1709 1710 newHist->bounds->data.F32[ i ] = bounds->data.F32[ i ]; 1711 } 1712 1710 1713 // Allocate the bins, and initialize them to zero. If there are N bounds, 1711 1714 // then there are N-1 bins. … … 1713 1716 newHist->nums->n = newHist->nums->nalloc; 1714 1717 for ( i = 0;i < newHist->nums->n;i++ ) { 1715 newHist->nums->data.U32[ i ] = 0;1716 }1717 1718 newHist->nums->data.U32[ i ] = 0; 1719 } 1720 1718 1721 // Initialize the other members. 1719 1722 newHist->minNum = 0; 1720 1723 newHist->maxNum = 0; 1721 1724 newHist->uniform = false; 1722 1725 1723 1726 return ( newHist ); 1724 1727 } … … 1755 1758 int binNum = 0; // A temporary bin number 1756 1759 int numBins = 0; // The total number of bins 1757 1760 1758 1761 // NOTE: Verify that this is the correct action. 1759 1762 if ( out == NULL ) { 1760 return ( NULL );1761 }1762 1763 return ( NULL ); 1764 } 1765 1763 1766 // Check the specified output histogram for type psF32 1764 1767 if ( out->bounds->type.type != PS_TYPE_F32 ) { 1765 psAbort( __func__,1766 "Only data type PS_TYPE_F32 for the output.bounds member." );1767 }1768 1768 psAbort( __func__, 1769 "Only data type PS_TYPE_F32 for the output.bounds member." ); 1770 } 1771 1769 1772 if ( out->nums->type.type != PS_TYPE_U32 ) { 1770 psAbort( __func__,1771 "Only data type PS_TYPE_U32 for output.nums member." );1772 }1773 1773 psAbort( __func__, 1774 "Only data type PS_TYPE_U32 for output.nums member." ); 1775 } 1776 1774 1777 // NOTE: Verify that this is the correct action. 1775 1778 if ( in == NULL ) { 1776 return ( out );1777 }1778 1779 return ( out ); 1780 } 1781 1779 1782 if ( in->type.type != PS_TYPE_F32 ) { 1783 psAbort( __func__, 1784 "Only data type PS_TYPE_F32 is currently supported (0x%x).", 1785 in->type.type ); 1786 } 1787 1788 if ( mask != NULL ) { 1789 if ( in->n != mask->n ) { 1780 1790 psAbort( __func__, 1781 "Only data type PS_TYPE_F32 is currently supported (0x%x).", 1782 in->type.type ); 1783 } 1784 1785 if ( mask != NULL ) { 1786 if ( in->n != mask->n ) { 1787 psAbort( __func__, 1788 "Vector data and vector mask are of different sizes." ); 1789 } 1790 if ( mask->type.type != PS_TYPE_U8 ) { 1791 psAbort( __func__, "Vector mask must be type PS_TYPE_U8" ); 1792 } 1793 } 1791 "Vector data and vector mask are of different sizes." ); 1792 } 1793 if ( mask->type.type != PS_TYPE_U8 ) { 1794 psAbort( __func__, "Vector mask must be type PS_TYPE_U8" ); 1795 } 1796 } 1794 1797 // NOTE: determine the correct action for a variety of other cases: 1795 1798 // in vector has 0 elements, and histogram structure has zero bins. 1796 1799 1797 1800 numBins = out->nums->n; 1798 1801 for ( i = 0;i < in->n;i++ ) { 1799 // Check if this pixel is masked, and if so, skip it. 1800 if ( ( mask == NULL ) || 1801 ( ( mask != NULL ) && ( !( mask->data.U8[ i ] & maskVal ) ) ) ) { 1802 // Check if this pixel is below the minimum value, and if so 1803 // count it, then skip it. 1804 if ( in->data.F32[ i ] < out->bounds->data.F32[ 0 ] ) { 1805 out->minNum++; 1806 // Check if this pixel is above the maximum value, and if so 1807 // count it, then skip it. 1808 } else if ( in->data.F32[ i ] > out->bounds->data.F32[ numBins ] ) { 1809 out->maxNum++; 1810 } else { 1811 // If this is a uniform histogram, determining the correct 1812 // number is trivial. 1813 if ( out->uniform == true ) { 1814 binSize = out->bounds->data.F32[ 1 ] - out->bounds->data.F32[ 0 ]; 1815 binNum = ( int ) ( ( in->data.F32[ i ] - out->bounds->data.F32[ 0 ] ) / 1816 binSize ); 1817 1818 // NOTE: This next if-statement really shouldn't be necessary. 1819 // However, do to numerical lack of precision, we occasionally 1820 // produce a binNum outside the range of bins. 1821 if ( binNum >= out->nums->n ) { 1822 binNum = out->nums->n - 1; 1823 } 1824 1825 ( out->nums->data.S32[ binNum ] ) ++; 1826 1827 // If this is a non-uniform histogram, determining the correct 1828 // bin number requires a bit more work. 1829 } else { 1830 // NOTE: This is slow. Put a smarter algorithm here to 1831 // find the correct bin number (bin search, probably) 1832 for ( j = 0;j < ( out->bounds->n ) - 1;j++ ) { 1833 if ( ( out->bounds->data.S32[ j ] <= in->data.F32[ i ] ) && 1834 ( in->data.F32[ i ] <= out->bounds->data.S32[ j + 1 ] ) ) { 1835 ( out->nums->data.S32[ j ] ) ++; 1836 } 1837 } 1838 } 1802 // Check if this pixel is masked, and if so, skip it. 1803 if ( ( mask == NULL ) || 1804 ( ( mask != NULL ) && ( !( mask->data.U8[ i ] & maskVal ) ) ) ) { 1805 // Check if this pixel is below the minimum value, and if so 1806 // count it, then skip it. 1807 if ( in->data.F32[ i ] < out->bounds->data.F32[ 0 ] ) { 1808 out->minNum++; 1809 // Check if this pixel is above the maximum value, and if so 1810 // count it, then skip it. 1811 } else 1812 if ( in->data.F32[ i ] > out->bounds->data.F32[ numBins ] ) { 1813 out->maxNum++; 1814 } else { 1815 // If this is a uniform histogram, determining the correct 1816 // number is trivial. 1817 if ( out->uniform == true ) { 1818 binSize = out->bounds->data.F32[ 1 ] - out->bounds->data.F32[ 0 ]; 1819 binNum = ( int ) ( ( in->data.F32[ i ] - out->bounds->data.F32[ 0 ] ) / 1820 binSize ); 1821 1822 // NOTE: This next if-statement really shouldn't be necessary. 1823 // However, do to numerical lack of precision, we occasionally 1824 // produce a binNum outside the range of bins. 1825 if ( binNum >= out->nums->n ) { 1826 binNum = out->nums->n - 1; 1839 1827 } 1840 } 1841 } 1828 1829 ( out->nums->data.S32[ binNum ] ) ++; 1830 1831 // If this is a non-uniform histogram, determining the correct 1832 // bin number requires a bit more work. 1833 } else { 1834 // NOTE: This is slow. Put a smarter algorithm here to 1835 // find the correct bin number (bin search, probably) 1836 for ( j = 0;j < ( out->bounds->n ) - 1;j++ ) { 1837 if ( ( out->bounds->data.S32[ j ] <= in->data.F32[ i ] ) && 1838 ( in->data.F32[ i ] <= out->bounds->data.S32[ j + 1 ] ) ) { 1839 ( out->nums->data.S32[ j ] ) ++; 1840 } 1841 } 1842 } 1843 } 1844 } 1845 } 1842 1846 return ( out ); 1843 1847 } … … 1859 1863 int i = 0; 1860 1864 psVector *tmp = NULL; 1861 1865 1862 1866 if ( in->type.type == PS_TYPE_S32 ) { 1867 tmp = psVectorAlloc( in->n, PS_TYPE_F32 ); 1868 for ( i = 0;i < in->n;i++ ) { 1869 tmp->data.F32[ i ] = ( float ) in->data.S32[ i ]; 1870 } 1871 } else 1872 if ( in->type.type == PS_TYPE_U32 ) { 1863 1873 tmp = psVectorAlloc( in->n, PS_TYPE_F32 ); 1864 1874 for ( i = 0;i < in->n;i++ ) { 1865 tmp->data.F32[ i ] = ( float ) in->data.S32[ i ]; 1866 } 1867 } else if ( in->type.type == PS_TYPE_U32 ) { 1868 tmp = psVectorAlloc( in->n, PS_TYPE_F32 ); 1869 for ( i = 0;i < in->n;i++ ) { 1870 tmp->data.F32[ i ] = ( float ) in->data.U32[ i ]; 1871 } 1872 } else if ( in->type.type == PS_TYPE_F64 ) { 1873 tmp = psVectorAlloc( in->n, PS_TYPE_F32 ); 1874 for ( i = 0;i < in->n;i++ ) { 1875 tmp->data.F32[ i ] = ( float ) in->data.U32[ i ]; 1876 } 1877 } else 1878 if ( in->type.type == PS_TYPE_F64 ) { 1879 tmp = psVectorAlloc( in->n, PS_TYPE_F32 ); 1880 for ( i = 0;i < in->n;i++ ) { 1875 1881 tmp->data.F32[ i ] = ( float ) in->data.F64[ i ]; 1876 1882 } 1877 } else if ( in->type.type == PS_TYPE_F32 ) { 1878 // do nothing 1879 } else { 1880 psAbort( __func__, "unsupported vector type 0x%x\n", in->type.type ); 1881 } 1883 } else 1884 if ( in->type.type == PS_TYPE_F32 ) { 1885 // do nothing 1886 } else { 1887 psAbort( __func__, "unsupported vector type 0x%x\n", in->type.type ); 1888 } 1882 1889 return ( tmp ); 1883 1890 } … … 1908 1915 psVector * inF32; 1909 1916 int mustFreeTmp = 1; 1910 1917 1911 1918 // NOTE: Verify that this is the correct action. 1912 1919 if ( in == NULL ) { 1913 return ( stats );1914 }1920 return ( stats ); 1921 } 1915 1922 if ( stats == NULL ) { 1916 return ( NULL );1917 }1918 1923 return ( NULL ); 1924 } 1925 1919 1926 inF32 = p_psConvertToF32( stats, in, mask, maskVal ); 1920 1927 if ( inF32 == NULL ) { 1921 inF32 = in;1922 mustFreeTmp = 0;1923 }1924 1928 inF32 = in; 1929 mustFreeTmp = 0; 1930 } 1931 1925 1932 // XXX: Should we abort if (stats->min == stats->max)? 1926 1933 if ( ( stats->options & PS_STAT_USE_RANGE ) && 1927 1934 ( stats->min >= stats->max ) ) { 1928 psAbort( __func__, "psVectorStats() called with range: %f to %f\n",1929 stats->min, stats->max );1930 }1931 1935 psAbort( __func__, "psVectorStats() called with range: %f to %f\n", 1936 stats->min, stats->max ); 1937 } 1938 1932 1939 // PS_CHECK_VECTOR_TYPE(in, PS_TYPE_F32); 1933 1940 if ( mask != NULL ) { 1934 PS_CHECK_NULL_VECTOR( mask );1935 PS_CHECK_EMPTY_VECTOR( mask );1936 PS_CHECK_VECTOR_SIZE_EQUAL( mask, in );1937 PS_CHECK_VECTOR_TYPE( mask, PS_TYPE_U8 );1938 }1939 1941 PS_CHECK_NULL_VECTOR( mask ); 1942 PS_CHECK_EMPTY_VECTOR( mask ); 1943 PS_CHECK_VECTOR_SIZE_EQUAL( mask, in ); 1944 PS_CHECK_VECTOR_TYPE( mask, PS_TYPE_U8 ); 1945 } 1946 1940 1947 // ************************************************************************ 1941 1948 if ( stats->options & PS_STAT_SAMPLE_MEAN ) { 1942 p_psVectorSampleMean( in, mask, maskVal, stats );1943 }1944 1949 p_psVectorSampleMean( in, mask, maskVal, stats ); 1950 } 1951 1945 1952 // ************************************************************************ 1946 1953 if ( stats->options & PS_STAT_SAMPLE_MEDIAN ) { 1947 p_psVectorSampleMedian( in, mask, maskVal, stats );1948 }1949 1954 p_psVectorSampleMedian( in, mask, maskVal, stats ); 1955 } 1956 1950 1957 // ************************************************************************ 1951 1958 // NOTE: The Stdev calculation requires the mean. Should we assume the 1952 1959 // mean has already been calculated? Or should we always calculate it? 1953 1960 if ( stats->options & PS_STAT_SAMPLE_STDEV ) { 1954 p_psVectorSampleMean( in, mask, maskVal, stats );1955 p_psVectorSampleStdev( in, mask, maskVal, stats );1956 }1957 1961 p_psVectorSampleMean( in, mask, maskVal, stats ); 1962 p_psVectorSampleStdev( in, mask, maskVal, stats ); 1963 } 1964 1958 1965 // ************************************************************************ 1959 1966 if ( stats->options & PS_STAT_SAMPLE_QUARTILE ) { 1960 p_psVectorSampleQuartiles( in, mask, maskVal, stats );1961 }1962 1967 p_psVectorSampleQuartiles( in, mask, maskVal, stats ); 1968 } 1969 1963 1970 // Since the various robust stats quantities share much computation, they 1964 1971 // are grouped together in a single private function: … … 1969 1976 ( stats->options & PS_STAT_ROBUST_STDEV ) || 1970 1977 ( stats->options & PS_STAT_ROBUST_QUARTILE ) ) { 1971 p_psVectorRobustStats( in, mask, maskVal, stats );1972 }1973 1978 p_psVectorRobustStats( in, mask, maskVal, stats ); 1979 } 1980 1974 1981 if ( ( stats->options & PS_STAT_CLIPPED_MEAN ) || 1975 1982 ( stats->options & PS_STAT_CLIPPED_STDEV ) ) { 1976 p_psVectorClippedStats( in, mask, maskVal, stats );1977 }1978 1983 p_psVectorClippedStats( in, mask, maskVal, stats ); 1984 } 1985 1979 1986 // ************************************************************************ 1980 1987 if ( stats->options & PS_STAT_MAX ) { 1981 p_psVectorMax( in, mask, maskVal, stats );1982 }1983 1988 p_psVectorMax( in, mask, maskVal, stats ); 1989 } 1990 1984 1991 // ************************************************************************ 1985 1992 if ( stats->options & PS_STAT_MIN ) { 1986 p_psVectorMin( in, mask, maskVal, stats );1987 }1988 1993 p_psVectorMin( in, mask, maskVal, stats ); 1994 } 1995 1989 1996 if ( mustFreeTmp == 1 ) { 1990 psFree( inF32 );1991 }1997 psFree( inF32 ); 1998 } 1992 1999 return ( stats ); 1993 2000 } -
trunk/psLib/src/math/psStats.h
r1322 r1385 9 9 * @author George Gusciora, MHPCC 10 10 * 11 * @version $Revision: 1.1 8$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-0 7-29 01:59:06$11 * @version $Revision: 1.19 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-08-04 23:37:39 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/mathtypes/psImage.c
r1263 r1385 9 9 * @author Ross Harman, MHPCC 10 10 * 11 * @version $Revision: 1.3 5$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-0 7-22 20:42:22$11 * @version $Revision: 1.36 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-08-04 23:37:39 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/mathtypes/psImage.h
r1263 r1385 11 11 * @author Ross Harman, MHPCC 12 12 * 13 * @version $Revision: 1.2 5$ $Name: not supported by cvs2svn $14 * @date $Date: 2004-0 7-22 20:42:22$13 * @version $Revision: 1.26 $ $Name: not supported by cvs2svn $ 14 * @date $Date: 2004-08-04 23:37:39 $ 15 15 * 16 16 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/mathtypes/psScalar.c
r1162 r1385 8 8 * @author Ross Harman, MHPCC 9 9 * 10 * @version $Revision: 1. 3$ $Name: not supported by cvs2svn $11 * @date $Date: 2004-0 7-01 00:14:40$10 * @version $Revision: 1.4 $ $Name: not supported by cvs2svn $ 11 * @date $Date: 2004-08-04 23:37:39 $ 12 12 * 13 13 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/mathtypes/psScalar.h
r1060 r1385 10 10 * @author Ross Harman, MHPCC 11 11 * 12 * @version $Revision: 1. 1$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-0 6-18 23:36:02$12 * @version $Revision: 1.2 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2004-08-04 23:37:39 $ 14 14 * 15 15 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/mathtypes/psVector.c
r1360 r1385 8 8 * @author Ross Harman, MHPCC 9 9 * 10 * @version $Revision: 1.1 7$ $Name: not supported by cvs2svn $11 * @date $Date: 2004-0 7-31 02:28:10$10 * @version $Revision: 1.18 $ $Name: not supported by cvs2svn $ 11 * @date $Date: 2004-08-04 23:37:39 $ 12 12 * 13 13 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 63 63 psVector * psVec = NULL; 64 64 int elementSize = 0; 65 65 66 66 // Invalid nalloc 67 67 if ( nalloc < 1 ) { 68 psError( __func__, "Invalid value for nalloc. nalloc: %d\n", nalloc );69 return NULL;70 }71 68 psError( __func__, "Invalid value for nalloc. nalloc: %d\n", nalloc ); 69 return NULL; 70 } 71 72 72 elementSize = PSELEMTYPE_SIZEOF( elemType ); 73 73 74 74 // Create vector struct 75 75 psVec = ( psVector * ) psAlloc( sizeof( psVector ) ); 76 76 p_psMemSetDeallocator( psVec, ( psFreeFcn ) vectorFree ); 77 77 78 78 psVec->type.dimen = PS_DIMEN_VECTOR; 79 79 psVec->type.type = elemType; 80 80 psVec->nalloc = nalloc; 81 81 psVec->n = nalloc; 82 82 83 83 // Create vector data array 84 84 psVec->data.V = psAlloc( nalloc * elementSize ); 85 85 86 86 return psVec; 87 87 } … … 91 91 int elementSize = 0; 92 92 psElemType elemType; 93 93 94 94 // Invalid nalloc 95 95 if ( nalloc < 1 ) { 96 psError( __func__, "Invalid value for realloc (%d)\n", nalloc );97 return NULL;98 }99 96 psError( __func__, "Invalid value for realloc (%d)\n", nalloc ); 97 return NULL; 98 } 99 100 100 if ( in == NULL ) { 101 psError( __func__, "Null input vector\n" ); 102 return NULL; 103 } else if ( in->nalloc != nalloc ) { // No need to realloc to same size 101 psError( __func__, "Null input vector\n" ); 102 return NULL; 103 } else 104 if ( in->nalloc != nalloc ) { // No need to realloc to same size 104 105 elemType = in->type.type; 105 106 elementSize = PSELEMTYPE_SIZEOF( elemType ); 106 107 if ( nalloc < in->n ) { 107 in->n = nalloc;108 }109 108 in->n = nalloc; 109 } 110 110 111 // Realloc after decrementation to avoid accessing freed array elements 111 112 in->data.V = psRealloc( in->data.V, nalloc * elementSize ); 112 113 in->nalloc = nalloc; 113 114 } 114 115 115 116 return in; 116 117 } … … 119 120 { 120 121 psElemType elemType; 121 122 122 123 if ( in == NULL ) { 123 return psVectorAlloc( nalloc, type );124 }125 124 return psVectorAlloc( nalloc, type ); 125 } 126 126 127 elemType = in->type.type; 127 128 128 129 if ( in->nalloc == nalloc && elemType == type ) { 129 // it is proper size/type already130 return in;131 }132 130 // it is proper size/type already 131 return in; 132 } 133 133 134 // Invalid nalloc 134 135 if ( nalloc < 1 ) { 135 psError( __func__, "Invalid value for nalloc (%d)\n", nalloc );136 psFree( in );137 return NULL;138 }139 140 136 psError( __func__, "Invalid value for nalloc (%d)\n", nalloc ); 137 psFree( in ); 138 return NULL; 139 } 140 141 141 142 in->data.V = psRealloc( in->data.V, nalloc * PSELEMTYPE_SIZEOF( type ) ); 142 143 143 144 in->type.type = type; 144 145 in->nalloc = nalloc; 145 146 in->n = nalloc; 146 147 147 148 return in; 148 149 } … … 156 157 void *outVec = NULL; 157 158 psElemType inType = 0; 158 159 159 160 if ( inVector == NULL ) { 160 psError( __func__, " : Line %d - Null input vector\n", __LINE__ );161 return outVector;162 }163 161 psError( __func__, " : Line %d - Null input vector\n", __LINE__ ); 162 return outVector; 163 } 164 164 165 inType = inVector->type.type; 165 166 inN = inVector->n; 166 167 inVec = inVector->data.V; 167 168 elSize = PSELEMTYPE_SIZEOF( inType ); 168 169 169 170 if ( outVector == NULL ) { 170 outVector = psVectorAlloc( inN, inType );171 outVector->n = inVector->n;172 }173 171 outVector = psVectorAlloc( inN, inType ); 172 outVector->n = inVector->n; 173 } 174 174 175 outN = outVector->n; 175 176 outVec = outVector->data.V; 176 177 177 178 if ( inN != outN ) { 178 psError( __func__, " : Line %d - Input and output vector sizes are not equal: in=%d out=%d\n", __LINE__,179 inN, outN );180 return outVector;181 }182 179 psError( __func__, " : Line %d - Input and output vector sizes are not equal: in=%d out=%d\n", __LINE__, 180 inN, outN ); 181 return outVector; 182 } 183 183 184 if ( inType != outVector->type.type ) { 184 psError( __func__, " : Line %d - Input and output vectors are not same type: in=%d out=%d\n", __LINE__,185 inType, outVector->type.type );186 return outVector;187 }188 185 psError( __func__, " : Line %d - Input and output vectors are not same type: in=%d out=%d\n", __LINE__, 186 inType, outVector->type.type ); 187 return outVector; 188 } 189 189 190 if ( inN == 0 ) { 190 psError( __func__, " : Line %d - No elements in use for input vector\n", __LINE__ );191 return outVector;192 }193 191 psError( __func__, " : Line %d - No elements in use for input vector\n", __LINE__ ); 192 return outVector; 193 } 194 194 195 if ( outN == 0 ) { 195 psError( __func__, " : Line %d - No elements in use for output vector\n", __LINE__ );196 return outVector;197 }198 196 psError( __func__, " : Line %d - No elements in use for output vector\n", __LINE__ ); 197 return outVector; 198 } 199 199 200 // Copy input vector values into output vector 200 201 memcpy( outVec, inVec, elSize * outN ); 201 202 202 203 // Sort output vector 203 204 switch ( inType ) { 204 case PS_TYPE_U8:205 qsort( outVec, inN, elSize, psCompareU8 );206 break;207 case PS_TYPE_U16:208 qsort( outVec, inN, elSize, psCompareU16 );209 break;210 case PS_TYPE_U32:211 qsort( outVec, inN, elSize, psCompareU32 );212 break;213 case PS_TYPE_U64:214 qsort( outVec, inN, elSize, psCompareU64 );215 break;216 case PS_TYPE_S8:217 qsort( outVec, inN, elSize, psCompareS8 );218 break;219 case PS_TYPE_S16:220 qsort( outVec, inN, elSize, psCompareS16 );221 break;222 case PS_TYPE_S32:223 qsort( outVec, inN, elSize, psCompareS32 );224 break;225 case PS_TYPE_S64:226 qsort( outVec, inN, elSize, psCompareS64 );227 break;228 case PS_TYPE_F32:229 qsort( outVec, inN, elSize, psCompareF32 );230 break;231 case PS_TYPE_F64:232 qsort( outVec, inN, elSize, psCompareF64 );233 break;234 default:235 psError( __func__, " : Line %d - Invalid psType\n", __LINE__ );236 }237 205 case PS_TYPE_U8: 206 qsort( outVec, inN, elSize, psCompareU8 ); 207 break; 208 case PS_TYPE_U16: 209 qsort( outVec, inN, elSize, psCompareU16 ); 210 break; 211 case PS_TYPE_U32: 212 qsort( outVec, inN, elSize, psCompareU32 ); 213 break; 214 case PS_TYPE_U64: 215 qsort( outVec, inN, elSize, psCompareU64 ); 216 break; 217 case PS_TYPE_S8: 218 qsort( outVec, inN, elSize, psCompareS8 ); 219 break; 220 case PS_TYPE_S16: 221 qsort( outVec, inN, elSize, psCompareS16 ); 222 break; 223 case PS_TYPE_S32: 224 qsort( outVec, inN, elSize, psCompareS32 ); 225 break; 226 case PS_TYPE_S64: 227 qsort( outVec, inN, elSize, psCompareS64 ); 228 break; 229 case PS_TYPE_F32: 230 qsort( outVec, inN, elSize, psCompareF32 ); 231 break; 232 case PS_TYPE_F64: 233 qsort( outVec, inN, elSize, psCompareF64 ); 234 break; 235 default: 236 psError( __func__, " : Line %d - Invalid psType\n", __LINE__ ); 237 } 238 238 239 return outVector; 239 240 } … … 241 242 #define SORT_INDICES(TYPE) \ 242 243 for(i=0; i<inN; i++) { \ 243 for(j=0; j<inN; j++) { \244 diff = fabs((double)tmpVector->data.TYPE[i] - inVec[j]); \245 if(diff < FLT_EPSILON) { \246 outVec[i] = j; \247 break; \248 } \249 } \250 }251 244 for(j=0; j<inN; j++) { \ 245 diff = fabs((double)tmpVector->data.TYPE[i] - inVec[j]); \ 246 if(diff < FLT_EPSILON) { \ 247 outVec[i] = j; \ 248 break; \ 249 } \ 250 } \ 251 } 252 252 253 psVector *psVectorSortIndex( psVector *restrict outVector, const psVector *restrict inVector ) 253 254 { … … 261 262 psVector *tmpVector = NULL; 262 263 psElemType inType = 0; 263 264 264 265 if ( inVector == NULL ) { 265 psError( __func__, " : Line %d - Null input vector\n", __LINE__ );266 return outVector;267 }268 266 psError( __func__, " : Line %d - Null input vector\n", __LINE__ ); 267 return outVector; 268 } 269 269 270 inN = inVector->n; 270 271 inVec = inVector->data.V; 271 272 inType = inVector->type.type; 272 273 273 274 if ( outVector == NULL ) { 274 outVector = psVectorAlloc( inN, PS_TYPE_U32 );275 outVector->n = inN;276 }277 275 outVector = psVectorAlloc( inN, PS_TYPE_U32 ); 276 outVector->n = inN; 277 } 278 278 279 outN = outVector->n; 279 280 outVec = outVector->data.V; 280 281 281 282 if ( inN != outN ) { 282 psError( __func__, " : Line %d - Input and output vector sizes are not equal: in=%d out=%d\n",283 __LINE__, inN, outN );284 return outVector;285 }286 283 psError( __func__, " : Line %d - Input and output vector sizes are not equal: in=%d out=%d\n", 284 __LINE__, inN, outN ); 285 return outVector; 286 } 287 287 288 if ( outVector->type.type != PS_TYPE_U32 ) { 288 psError( __func__, " : Line %d - Output vector is not of type U32: out=%d\n",289 __LINE__, outVector->type.type );290 return outVector;291 }292 289 psError( __func__, " : Line %d - Output vector is not of type U32: out=%d\n", 290 __LINE__, outVector->type.type ); 291 return outVector; 292 } 293 293 294 tmpVector = psVectorAlloc( inN, inType ); 294 295 tmpVector->n = inN; 295 296 tmpVector = psVectorSort( tmpVector, inVector ); 296 297 297 298 // Sort output vector 298 299 switch ( inType ) { 299 case PS_TYPE_U8:300 SORT_INDICES( U8 );301 break;302 case PS_TYPE_U16:303 SORT_INDICES( U16 );304 break;305 case PS_TYPE_U32:306 SORT_INDICES( U32 );307 break;308 case PS_TYPE_U64:309 SORT_INDICES( U64 );310 break;311 case PS_TYPE_S8:312 SORT_INDICES( S8 );313 break;314 case PS_TYPE_S16:315 SORT_INDICES( S16 );316 break;317 case PS_TYPE_S32:318 SORT_INDICES( S32 );319 break;320 case PS_TYPE_S64:321 SORT_INDICES( S64 );322 break;323 case PS_TYPE_F32:324 SORT_INDICES( F32 );325 break;326 case PS_TYPE_F64:327 SORT_INDICES( F64 );328 break;329 default:330 psError( __func__, " : Line %d - Invalid psType\n", __LINE__ );331 }332 300 case PS_TYPE_U8: 301 SORT_INDICES( U8 ); 302 break; 303 case PS_TYPE_U16: 304 SORT_INDICES( U16 ); 305 break; 306 case PS_TYPE_U32: 307 SORT_INDICES( U32 ); 308 break; 309 case PS_TYPE_U64: 310 SORT_INDICES( U64 ); 311 break; 312 case PS_TYPE_S8: 313 SORT_INDICES( S8 ); 314 break; 315 case PS_TYPE_S16: 316 SORT_INDICES( S16 ); 317 break; 318 case PS_TYPE_S32: 319 SORT_INDICES( S32 ); 320 break; 321 case PS_TYPE_S64: 322 SORT_INDICES( S64 ); 323 break; 324 case PS_TYPE_F32: 325 SORT_INDICES( F32 ); 326 break; 327 case PS_TYPE_F64: 328 SORT_INDICES( F64 ); 329 break; 330 default: 331 psError( __func__, " : Line %d - Invalid psType\n", __LINE__ ); 332 } 333 333 334 // Free temp memory 334 335 psFree( tmpVector ); 335 336 336 337 return outVector; 337 338 } … … 340 341 { 341 342 if ( psVec == NULL ) { 342 return ;343 }344 343 return ; 344 } 345 345 346 psFree( psVec->data.V ); 346 347 } -
trunk/psLib/src/mathtypes/psVector.h
r1233 r1385 11 11 * @author Ross Harman, MHPCC 12 12 * 13 * @version $Revision: 1.1 3$ $Name: not supported by cvs2svn $14 * @date $Date: 2004-0 7-15 23:52:33$13 * @version $Revision: 1.14 $ $Name: not supported by cvs2svn $ 14 * @date $Date: 2004-08-04 23:37:39 $ 15 15 * 16 16 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/sys/psAbort.c
r1138 r1385 9 9 * @author Eric Van Alst, MHPCC 10 10 * 11 * @version $Revision: 1. 5$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-0 6-30 01:17:20$11 * @version $Revision: 1.6 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-08-04 23:37:39 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/sys/psError.c
r1138 r1385 10 10 * @author Eric Van Alst, MHPCC 11 11 * 12 * @version $Revision: 1. 7$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-0 6-30 01:17:20$12 * @version $Revision: 1.8 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2004-08-04 23:37:39 $ 14 14 * 15 15 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/sys/psLogMsg.c
r1153 r1385 11 11 * @author George Gusciora, MHPCC 12 12 * 13 * @version $Revision: 1.2 0$ $Name: not supported by cvs2svn $14 * @date $Date: 2004-0 6-30 20:22:37$13 * @version $Revision: 1.21 $ $Name: not supported by cvs2svn $ 14 * @date $Date: 2004-08-04 23:37:39 $ 15 15 * 16 16 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 132 132 psError(__func__,"The location, %s, for protocol 'dest' is invalid.",location); 133 133 return 1; 134 } else if (strcmp(protocol,"file") == 0) { 135 FILE* file = fopen(location,"w"); 136 if (file == NULL) { 137 psError(__func__,"Could not open file '%s' for output.",location); 138 return 1; 139 } 140 if (logDest != NULL && logDest != stderr && logDest != stdout) { 141 fclose(logDest); 142 } 143 logDest = file; 144 return 0; 145 } 134 } else 135 if (strcmp(protocol,"file") == 0) { 136 FILE* file = fopen(location,"w"); 137 if (file == NULL) { 138 psError(__func__,"Could not open file '%s' for output.",location); 139 return 1; 140 } 141 if (logDest != NULL && logDest != stderr && logDest != stdout) { 142 fclose(logDest); 143 } 144 logDest = file; 145 return 0; 146 } 146 147 147 148 psError(__func__,"Do not know how to handle the protocol '%s'.",protocol); … … 336 337 if (head_ptr > head) { 337 338 *head_ptr++ = '|'; 338 } else if (!logMsg) { // no output desired 339 return; 340 } 339 } else 340 if (!logMsg) { // no output desired 341 return; 342 } 341 343 *head_ptr = '\0'; 342 344 -
trunk/psLib/src/sys/psLogMsg.h
r1153 r1385 11 11 * @author George Gusciora, MHPCC 12 12 * 13 * @version $Revision: 1.1 0$ $Name: not supported by cvs2svn $14 * @date $Date: 2004-0 6-30 20:22:37$13 * @version $Revision: 1.11 $ $Name: not supported by cvs2svn $ 14 * @date $Date: 2004-08-04 23:37:39 $ 15 15 * 16 16 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/sys/psMemory.c
r1360 r1385 8 8 * @author Robert Lupton, Princeton University 9 9 * 10 * @version $Revision: 1.3 0$ $Name: not supported by cvs2svn $11 * @date $Date: 2004-0 7-31 02:28:10$10 * @version $Revision: 1.31 $ $Name: not supported by cvs2svn $ 11 * @date $Date: 2004-08-04 23:37:39 $ 12 12 * 13 13 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 47 47 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL 48 48 }; 49 49 50 50 #ifdef PS_MEM_DEBUG 51 51 static psMemBlock* deadBlockList; // a place to put dead memBlocks in debug mode. … … 62 62 { 63 63 void * ptr = NULL; 64 64 65 65 pthread_mutex_lock( &recycleMemBlockListMutex ); 66 66 int level = recycleBins - 1; 67 67 while ( level >= 0 && ptr == NULL ) { 68 while ( recycleMemBlockList[ level ] != NULL && ptr == NULL ) {69 psMemBlock * old = recycleMemBlockList[ level ];70 recycleMemBlockList[ level ] = recycleMemBlockList[ level ] ->nextBlock;71 free( old );72 ptr = malloc( size );73 }74 level--;75 }68 while ( recycleMemBlockList[ level ] != NULL && ptr == NULL ) { 69 psMemBlock * old = recycleMemBlockList[ level ]; 70 recycleMemBlockList[ level ] = recycleMemBlockList[ level ] ->nextBlock; 71 free( old ); 72 ptr = malloc( size ); 73 } 74 level--; 75 } 76 76 pthread_mutex_unlock( &recycleMemBlockListMutex ); 77 77 78 78 return ptr; 79 79 } … … 84 84 { 85 85 psMemExhaustedCallback old = memExhaustedCallback; 86 86 87 87 if ( func != NULL ) { 88 memExhaustedCallback = func;89 } else {90 memExhaustedCallback = memExhaustedCallbackDefault;91 }92 88 memExhaustedCallback = func; 89 } else { 90 memExhaustedCallback = memExhaustedCallbackDefault; 91 } 92 93 93 return old; 94 94 } … … 98 98 { 99 99 if ( ptr->refCounter < 1 ) { 100 psError( __func__,101 "Block %ld allocated at %s:%d freed more than once at %s:%d\n",102 ptr->id, ptr->file, ptr->lineno, file, lineno );103 }104 100 psError( __func__, 101 "Block %ld allocated at %s:%d freed more than once at %s:%d\n", 102 ptr->id, ptr->file, ptr->lineno, file, lineno ); 103 } 104 105 105 if ( lineno > 0 ) { 106 psAbort( __func__, "Detected a problem in the memory system at %s:%d", file, lineno );107 }106 psAbort( __func__, "Detected a problem in the memory system at %s:%d", file, lineno ); 107 } 108 108 } 109 109 static psMemProblemCallback memProblemCallback = memProblemCallbackDefault; … … 112 112 { 113 113 psMemProblemCallback old = memProblemCallback; 114 114 115 115 if ( func != NULL ) { 116 memProblemCallback = func;117 } else {118 memProblemCallback = memProblemCallbackDefault;119 }120 116 memProblemCallback = func; 117 } else { 118 memProblemCallback = memProblemCallbackDefault; 119 } 120 121 121 return old; 122 122 } … … 133 133 psMemoryId old = p_psMemAllocateID; 134 134 p_psMemAllocateID = id; 135 135 136 136 return old; 137 137 } … … 141 141 psMemoryId old = p_psMemFreeID; 142 142 p_psMemFreeID = id; 143 143 144 144 return old; 145 145 } … … 154 154 { 155 155 static psMemoryId incr = 0; // "p_psMemAllocateID += incr" 156 156 157 157 return incr; 158 158 } … … 161 161 { 162 162 static psMemoryId incr = 0; // "p_psMemFreeID += incr" 163 163 164 164 return incr; 165 165 } … … 174 174 { 175 175 psMemFreeCallback old = memAllocateCallback; 176 176 177 177 if ( func != NULL ) { 178 memAllocateCallback = func;179 } else {180 memAllocateCallback = memAllocateCallbackDefault;181 }182 178 memAllocateCallback = func; 179 } else { 180 memAllocateCallback = memAllocateCallbackDefault; 181 } 182 183 183 return old; 184 184 } … … 187 187 { 188 188 psMemFreeCallback old = memFreeCallback; 189 189 190 190 if ( func != NULL ) { 191 memFreeCallback = func;192 } else {193 memFreeCallback = memFreeCallbackDefault;194 }195 191 memFreeCallback = func; 192 } else { 193 memFreeCallback = memFreeCallbackDefault; 194 } 195 196 196 return old; 197 197 } … … 206 206 id = memid + 1; 207 207 pthread_mutex_unlock( &memIdMutex ); 208 208 209 209 return id; 210 210 } … … 220 220 // n.b. since this is called by psMemCheckCorruption while the memblock list is mutex locked, 221 221 // we shouldn't call such things as p_psAlloc/p_psFree here. 222 222 223 223 if ( m == NULL ) { 224 psError( funcName, "Memory Corruption: NULL memory block found." );225 return 1;226 }227 224 psError( funcName, "Memory Corruption: NULL memory block found." ); 225 return 1; 226 } 227 228 228 if ( m->refCounter == 0 ) { 229 // using an unreferenced block of memory, are you?230 psError( __func__, "Memory Corruption: memory block %ld was freed but still used.",231 m->id );232 return 1;233 }234 229 // using an unreferenced block of memory, are you? 230 psError( __func__, "Memory Corruption: memory block %ld was freed but still used.", 231 m->id ); 232 return 1; 233 } 234 235 235 if ( m->startblock != P_PS_MEMMAGIC || m->endblock != P_PS_MEMMAGIC ) { 236 psError( funcName, "Memory Corruption: memory block %ld is corrupted (buffer underflow)",237 m->id );238 return 1;239 }236 psError( funcName, "Memory Corruption: memory block %ld is corrupted (buffer underflow)", 237 m->id ); 238 return 1; 239 } 240 240 if ( *( void** ) ( ( int8_t* ) ( m + 1 ) + m->userMemorySize ) != P_PS_MEMMAGIC ) { 241 psError( funcName, "Memory Corruption: memory block %ld is corrupted (buffer overflow)",242 m->id );243 return 1;244 }245 241 psError( funcName, "Memory Corruption: memory block %ld is corrupted (buffer overflow)", 242 m->id ); 243 return 1; 244 } 245 246 246 return 0; 247 247 } … … 250 250 { 251 251 int nbad = 0; // number of bad blocks 252 252 253 253 // get exclusive access to the memBlock list to avoid it changing on us while we use it. 254 254 pthread_mutex_lock( &memBlockListMutex ); 255 255 256 256 for ( psMemBlock * iter = lastMemBlockAllocated; iter != NULL; iter = iter->nextBlock ) { 257 if ( checkMemBlock( iter, __func__ ) ) {258 nbad++;259 260 memProblemCallback( iter, __func__, __LINE__ );261 262 if ( abort_on_error ) {263 // release the lock on the memblock list264 pthread_mutex_unlock( &memBlockListMutex );265 psAbort( __func__, "Detected memory corruption" );266 return nbad;267 }268 }269 }270 257 if ( checkMemBlock( iter, __func__ ) ) { 258 nbad++; 259 260 memProblemCallback( iter, __func__, __LINE__ ); 261 262 if ( abort_on_error ) { 263 // release the lock on the memblock list 264 pthread_mutex_unlock( &memBlockListMutex ); 265 psAbort( __func__, "Detected memory corruption" ); 266 return nbad; 267 } 268 } 269 } 270 271 271 // release the lock on the memblock list 272 272 pthread_mutex_unlock( &memBlockListMutex ); … … 278 278 279 279 psMemBlock * ptr = NULL; 280 280 281 281 // memory is of the size I want to bother recycling? 282 282 if ( size < P_PS_LARGE_BLOCK_SIZE ) { 283 // find the bin we need. 284 int level = 0; 285 while ( size > recycleBinSize[ level ] ) { 286 level++; 283 // find the bin we need. 284 int level = 0; 285 while ( size > recycleBinSize[ level ] ) { 286 level++; 287 } 288 // Are we in one of the bins 289 if ( level < recycleBins ) { 290 291 size = recycleBinSize[ level ]; // round-up size to next sized bin. 292 293 pthread_mutex_lock( &recycleMemBlockListMutex ); 294 295 if ( recycleMemBlockList[ level ] != NULL ) { 296 ptr = recycleMemBlockList[ level ]; 297 recycleMemBlockList[ level ] = ptr->nextBlock; 298 if ( recycleMemBlockList[ level ] != NULL ) { 299 recycleMemBlockList[ level ] ->previousBlock = NULL; 287 300 } 288 // Are we in one of the bins 289 if ( level < recycleBins ) { 290 291 size = recycleBinSize[ level ]; // round-up size to next sized bin. 292 293 pthread_mutex_lock( &recycleMemBlockListMutex ); 294 295 if ( recycleMemBlockList[ level ] != NULL ) { 296 ptr = recycleMemBlockList[ level ]; 297 recycleMemBlockList[ level ] = ptr->nextBlock; 298 if ( recycleMemBlockList[ level ] != NULL ) { 299 recycleMemBlockList[ level ] ->previousBlock = NULL; 300 } 301 size = ptr->userMemorySize; 302 } 303 304 pthread_mutex_unlock( &recycleMemBlockListMutex ); 305 } 306 } 307 301 size = ptr->userMemorySize; 302 } 303 304 pthread_mutex_unlock( &recycleMemBlockListMutex ); 305 } 306 } 307 308 308 if ( ptr == NULL ) { 309 ptr = malloc( sizeof( psMemBlock ) + size + sizeof( void* ) ); 310 309 ptr = malloc( sizeof( psMemBlock ) + size + sizeof( void* ) ); 310 311 if ( ptr == NULL ) { 312 ptr = memExhaustedCallback( size ); 311 313 if ( ptr == NULL ) { 312 ptr = memExhaustedCallback( size ); 313 if ( ptr == NULL ) { 314 psAbort( __func__, "Failed to allocate %u bytes at %s:%d", 315 size, file, lineno ); 316 } 317 } 318 319 ptr->startblock = P_PS_MEMMAGIC; 320 ptr->endblock = P_PS_MEMMAGIC; 321 ptr->userMemorySize = size; 322 pthread_mutex_init( &ptr->refCounterMutex, NULL ); 323 } 324 314 psAbort( __func__, "Failed to allocate %u bytes at %s:%d", 315 size, file, lineno ); 316 } 317 } 318 319 ptr->startblock = P_PS_MEMMAGIC; 320 ptr->endblock = P_PS_MEMMAGIC; 321 ptr->userMemorySize = size; 322 pthread_mutex_init( &ptr->refCounterMutex, NULL ); 323 } 324 325 325 // increment the memory id safely. 326 326 pthread_mutex_lock( &memBlockListMutex ); 327 327 *( psMemoryId* ) & ptr->id = ++memid; 328 328 pthread_mutex_unlock( &memBlockListMutex ); 329 329 330 330 ptr->file = file; 331 331 ptr->freeFcn = NULL; … … 333 333 *( void** ) ( ( int8_t* ) ( ptr + 1 ) + size ) = P_PS_MEMMAGIC; 334 334 ptr->previousBlock = NULL; 335 335 336 336 ptr->refCounter = 1; // one user so far 337 337 338 338 // need exclusive access of the memory block list now... 339 339 pthread_mutex_lock( &memBlockListMutex ); 340 340 341 341 // insert the new block to the front of the memBlock linked-list 342 342 ptr->nextBlock = lastMemBlockAllocated; 343 343 if ( ptr->nextBlock != NULL ) { 344 ptr->nextBlock->previousBlock = ptr;345 }344 ptr->nextBlock->previousBlock = ptr; 345 } 346 346 lastMemBlockAllocated = ptr; 347 347 348 348 pthread_mutex_unlock( &memBlockListMutex ); 349 349 350 350 // Did the user ask to be informed about this allocation? 351 351 if ( ptr->id == p_psMemAllocateID ) { 352 p_psMemAllocateID += memAllocateCallback( ptr );353 }354 352 p_psMemAllocateID += memAllocateCallback( ptr ); 353 } 354 355 355 // And return the user the memory that they allocated 356 356 return ptr + 1; // user memory … … 360 360 { 361 361 if ( vptr == NULL ) { 362 return p_psAlloc( size, file, lineno );363 } else {364 psMemBlock *ptr = ( ( psMemBlock * ) vptr ) - 1;365 bool isBlockLast = false;366 367 if ( checkMemBlock( ptr, __func__ ) != 0 ) {368 memProblemCallback( ptr, file, lineno );369 psAbort( file, "Realloc detected a memory corruption (id %ld @ %s:%d).",370 ptr->id, ptr->file, ptr->lineno );371 }372 373 pthread_mutex_lock( &memBlockListMutex );374 375 isBlockLast = ( ptr == lastMemBlockAllocated );376 377 ptr = ( psMemBlock* ) realloc( ptr, sizeof( psMemBlock ) + size + sizeof( void* ) );378 379 if ( ptr == NULL ) {380 psAbort( __func__, "Failed to reallocate %ld bytes at %s:%d",381 size, file, lineno );382 }383 384 ptr->userMemorySize = size;385 *( void** ) ( ( int8_t* ) ( ptr + 1 ) + size ) = P_PS_MEMMAGIC;386 387 if ( isBlockLast ) {388 lastMemBlockAllocated = ptr;389 }390 391 // the block location may have changed, so fix the linked list addresses.392 if ( ptr->nextBlock != NULL ) {393 ptr->nextBlock->previousBlock = ptr;394 }395 if ( ptr->previousBlock != NULL ) {396 ptr->previousBlock->nextBlock = ptr;397 }398 399 pthread_mutex_unlock( &memBlockListMutex );400 401 // Did the user ask to be informed about this allocation?402 if ( ptr->id == p_psMemAllocateID ) {403 p_psMemAllocateID += memAllocateCallback( ptr );404 }405 406 return ptr + 1; // usr memory407 }362 return p_psAlloc( size, file, lineno ); 363 } else { 364 psMemBlock *ptr = ( ( psMemBlock * ) vptr ) - 1; 365 bool isBlockLast = false; 366 367 if ( checkMemBlock( ptr, __func__ ) != 0 ) { 368 memProblemCallback( ptr, file, lineno ); 369 psAbort( file, "Realloc detected a memory corruption (id %ld @ %s:%d).", 370 ptr->id, ptr->file, ptr->lineno ); 371 } 372 373 pthread_mutex_lock( &memBlockListMutex ); 374 375 isBlockLast = ( ptr == lastMemBlockAllocated ); 376 377 ptr = ( psMemBlock* ) realloc( ptr, sizeof( psMemBlock ) + size + sizeof( void* ) ); 378 379 if ( ptr == NULL ) { 380 psAbort( __func__, "Failed to reallocate %ld bytes at %s:%d", 381 size, file, lineno ); 382 } 383 384 ptr->userMemorySize = size; 385 *( void** ) ( ( int8_t* ) ( ptr + 1 ) + size ) = P_PS_MEMMAGIC; 386 387 if ( isBlockLast ) { 388 lastMemBlockAllocated = ptr; 389 } 390 391 // the block location may have changed, so fix the linked list addresses. 392 if ( ptr->nextBlock != NULL ) { 393 ptr->nextBlock->previousBlock = ptr; 394 } 395 if ( ptr->previousBlock != NULL ) { 396 ptr->previousBlock->nextBlock = ptr; 397 } 398 399 pthread_mutex_unlock( &memBlockListMutex ); 400 401 // Did the user ask to be informed about this allocation? 402 if ( ptr->id == p_psMemAllocateID ) { 403 p_psMemAllocateID += memAllocateCallback( ptr ); 404 } 405 406 return ptr + 1; // usr memory 407 } 408 408 } 409 409 … … 421 421 int j = 0; 422 422 psMemBlock* topBlock = lastMemBlockAllocated; 423 423 424 424 pthread_mutex_lock( &memBlockListMutex ); 425 425 426 426 for ( psMemBlock * iter = topBlock; iter != NULL; iter = iter->nextBlock ) { 427 if ( ( psMemGetRefCounter( iter + 1 ) > 0 ) && ( iter->id >= id0 ) ) { 428 nleak++; 429 430 if ( fd != NULL ) { 431 if ( nleak == 1 ) { 432 fprintf( fd, " %20s:line ID\n", "file" ); 433 } 434 435 fprintf( fd, " %20s:%-4d %ld\n", iter->file, iter->lineno, iter->id ); 436 } 427 if ( ( psMemGetRefCounter( iter + 1 ) > 0 ) && ( iter->id >= id0 ) ) { 428 nleak++; 429 430 if ( fd != NULL ) { 431 if ( nleak == 1 ) { 432 fprintf( fd, " %20s:line ID\n", "file" ); 437 433 } 438 } 439 434 435 fprintf( fd, " %20s:%-4d %ld\n", iter->file, iter->lineno, iter->id ); 436 } 437 } 438 } 439 440 440 pthread_mutex_unlock( &memBlockListMutex ); 441 441 442 442 if ( nleak == 0 || arr == NULL ) { 443 return nleak;444 }445 443 return nleak; 444 } 445 446 446 *arr = p_psAlloc( nleak * sizeof( psMemBlock ), __FILE__, __LINE__ ); 447 447 pthread_mutex_lock( &memBlockListMutex ); 448 448 449 449 for ( psMemBlock * iter = topBlock; iter != NULL; iter = iter->nextBlock ) { 450 if ( ( psMemGetRefCounter( iter + 1 ) > 0 ) && ( iter->id >= id0 ) ) {451 ( *arr ) [ j++ ] = iter;452 if ( j == nleak ) { // found them all453 break;454 }455 }456 }457 450 if ( ( psMemGetRefCounter( iter + 1 ) > 0 ) && ( iter->id >= id0 ) ) { 451 ( *arr ) [ j++ ] = iter; 452 if ( j == nleak ) { // found them all 453 break; 454 } 455 } 456 } 457 458 458 pthread_mutex_unlock( &memBlockListMutex ); 459 459 460 460 return nleak; 461 461 } … … 463 463 /* 464 464 * Reference counting APIs 465 */ 465 */ 466 466 // return refCounter 467 467 psReferenceCount psMemGetRefCounter( void *vptr ) … … 469 469 psMemBlock * ptr; 470 470 unsigned int refCount; 471 471 472 472 if ( vptr == NULL ) { 473 return 0;474 }475 473 return 0; 474 } 475 476 476 ptr = ( ( psMemBlock * ) vptr ) - 1; 477 477 478 478 if ( checkMemBlock( ptr, __func__ ) != 0 ) { 479 memProblemCallback( ptr, __func__, __LINE__ );480 }481 479 memProblemCallback( ptr, __func__, __LINE__ ); 480 } 481 482 482 pthread_mutex_lock( &ptr->refCounterMutex ); 483 483 refCount = ptr->refCounter; 484 484 pthread_mutex_unlock( &ptr->refCounterMutex ); 485 485 486 486 return refCount; 487 487 } … … 490 490 { 491 491 psMemBlock * ptr; 492 492 493 493 if ( vptr == NULL ) { 494 return vptr;495 }496 494 return vptr; 495 } 496 497 497 ptr = ( ( psMemBlock * ) vptr ) - 1; 498 498 499 499 if ( checkMemBlock( ptr, __func__ ) ) { 500 memProblemCallback( ptr, file, lineno );501 }502 500 memProblemCallback( ptr, file, lineno ); 501 } 502 503 503 pthread_mutex_lock( &ptr->refCounterMutex ); 504 504 ptr->refCounter++; 505 505 pthread_mutex_unlock( &ptr->refCounterMutex ); 506 506 507 507 return vptr; 508 508 } … … 512 512 { 513 513 if ( vptr == NULL ) { 514 return NULL;515 }516 514 return NULL; 515 } 516 517 517 psMemBlock *ptr = ( ( psMemBlock * ) vptr ) - 1; 518 518 519 519 if ( checkMemBlock( ptr, __func__ ) != 0 ) { 520 memProblemCallback( ptr, file, lineno );521 return NULL;522 }523 520 memProblemCallback( ptr, file, lineno ); 521 return NULL; 522 } 523 524 524 pthread_mutex_lock( &ptr->refCounterMutex ); 525 525 526 526 if ( ptr->refCounter > 1 ) { 527 /// XXX - Probably should have another mutex here. 528 ptr->refCounter--; // multiple references, just decrement the count. 529 pthread_mutex_unlock( &ptr->refCounterMutex ); 530 527 /// XXX - Probably should have another mutex here. 528 ptr->refCounter--; // multiple references, just decrement the count. 529 pthread_mutex_unlock( &ptr->refCounterMutex ); 530 531 } else { 532 pthread_mutex_unlock( &ptr->refCounterMutex ); 533 534 // Did the user ask to be informed about this deallocation? 535 if ( ptr->id == p_psMemFreeID ) { 536 p_psMemFreeID += memFreeCallback( ptr ); 537 } 538 539 if ( ptr->freeFcn != NULL ) { 540 ptr->freeFcn( vptr ); 541 } 542 543 pthread_mutex_lock( &memBlockListMutex ); 544 545 // cut the memBlock out of the memBlock list 546 if ( ptr->nextBlock != NULL ) { 547 ptr->nextBlock->previousBlock = ptr->previousBlock; 548 } 549 if ( ptr->previousBlock != NULL ) { 550 ptr->previousBlock->nextBlock = ptr->nextBlock; 551 } 552 if ( lastMemBlockAllocated == ptr ) { 553 lastMemBlockAllocated = ptr->nextBlock; 554 } 555 556 pthread_mutex_unlock( &memBlockListMutex ); 557 558 559 // do we need to recycle? 560 if ( ptr->userMemorySize < P_PS_LARGE_BLOCK_SIZE ) { 561 562 int level = 1; 563 while ( ptr->userMemorySize >= recycleBinSize[ level ] ) { 564 level++; 565 } 566 level--; 567 568 ptr->refCounter = 0; 569 ptr->previousBlock = NULL; 570 571 pthread_mutex_lock( &recycleMemBlockListMutex ); 572 ptr->nextBlock = recycleMemBlockList[ level ]; 573 if ( recycleMemBlockList[ level ] != NULL ) { 574 recycleMemBlockList[ level ] ->previousBlock = ptr; 575 } 576 recycleMemBlockList[ level ] = ptr; 577 pthread_mutex_unlock( &recycleMemBlockListMutex ); 578 531 579 } else { 532 pthread_mutex_unlock( &ptr->refCounterMutex ); 533 534 // Did the user ask to be informed about this deallocation? 535 if ( ptr->id == p_psMemFreeID ) { 536 p_psMemFreeID += memFreeCallback( ptr ); 537 } 538 539 if ( ptr->freeFcn != NULL ) { 540 ptr->freeFcn( vptr ); 541 } 542 543 pthread_mutex_lock( &memBlockListMutex ); 544 545 // cut the memBlock out of the memBlock list 546 if ( ptr->nextBlock != NULL ) { 547 ptr->nextBlock->previousBlock = ptr->previousBlock; 548 } 549 if ( ptr->previousBlock != NULL ) { 550 ptr->previousBlock->nextBlock = ptr->nextBlock; 551 } 552 if ( lastMemBlockAllocated == ptr ) { 553 lastMemBlockAllocated = ptr->nextBlock; 554 } 555 556 pthread_mutex_unlock( &memBlockListMutex ); 557 558 559 // do we need to recycle? 560 if ( ptr->userMemorySize < P_PS_LARGE_BLOCK_SIZE ) { 561 562 int level = 1; 563 while ( ptr->userMemorySize >= recycleBinSize[ level ] ) { 564 level++; 565 } 566 level--; 567 568 ptr->refCounter = 0; 569 ptr->previousBlock = NULL; 570 571 pthread_mutex_lock( &recycleMemBlockListMutex ); 572 ptr->nextBlock = recycleMemBlockList[ level ]; 573 if ( recycleMemBlockList[ level ] != NULL ) { 574 recycleMemBlockList[ level ] ->previousBlock = ptr; 575 } 576 recycleMemBlockList[ level ] = ptr; 577 pthread_mutex_unlock( &recycleMemBlockListMutex ); 578 579 } else { 580 // memory is larger than I want to recycle. 581 #ifdef PS_MEM_DEBUG 582 ( void ) p_psRealloc( vptr, 0, file, lineno ); 583 ptr->previousBlock = NULL; 584 ptr->nextBlock = deadBlockList; 585 if ( deadBlockList != NULL ) { 586 deadBlockList->previous = ptr; 587 } 588 deadBlockList = ptr; 589 #else 590 591 pthread_mutex_destroy( &ptr->refCounterMutex ); 592 free( ptr ); 593 #endif 594 595 } 596 597 vptr = NULL; // since we freed it, make sure we return NULL. 598 } 599 580 // memory is larger than I want to recycle. 581 #ifdef PS_MEM_DEBUG 582 ( void ) p_psRealloc( vptr, 0, file, lineno ); 583 ptr->previousBlock = NULL; 584 ptr->nextBlock = deadBlockList; 585 if ( deadBlockList != NULL ) { 586 deadBlockList->previous = ptr; 587 } 588 deadBlockList = ptr; 589 #else 590 591 pthread_mutex_destroy( &ptr->refCounterMutex ); 592 free( ptr ); 593 #endif 594 595 } 596 597 vptr = NULL; // since we freed it, make sure we return NULL. 598 } 599 600 600 return vptr; 601 601 } … … 604 604 { 605 605 if ( vptr == NULL ) { 606 return ;607 }608 606 return ; 607 } 608 609 609 psMemBlock *ptr = ( ( psMemBlock * ) vptr ) - 1; 610 610 611 611 if ( checkMemBlock( ptr, __func__ ) != 0 ) { 612 memProblemCallback( ptr, __func__, __LINE__ );613 }614 612 memProblemCallback( ptr, __func__, __LINE__ ); 613 } 614 615 615 ptr->freeFcn = freeFcn; 616 616 617 617 } 618 618 psFreeFcn p_psMemGetDeallocator( void* vptr ) 619 619 { 620 620 if ( vptr == NULL ) { 621 return NULL;622 }623 621 return NULL; 622 } 623 624 624 psMemBlock *ptr = ( ( psMemBlock * ) vptr ) - 1; 625 625 626 626 if ( checkMemBlock( ptr, __func__ ) != 0 ) { 627 memProblemCallback( ptr, __func__, __LINE__ );628 }629 627 memProblemCallback( ptr, __func__, __LINE__ ); 628 } 629 630 630 return ptr->freeFcn; 631 631 } -
trunk/psLib/src/sys/psMemory.h
r1233 r1385 14 14 * @ingroup MemoryManagement 15 15 * 16 * @version $Revision: 1.2 1$ $Name: not supported by cvs2svn $17 * @date $Date: 2004-0 7-15 23:52:34$16 * @version $Revision: 1.22 $ $Name: not supported by cvs2svn $ 17 * @date $Date: 2004-08-04 23:37:39 $ 18 18 * 19 19 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/sys/psString.c
r635 r1385 8 8 * @author Eric Van Alst, MHPCC 9 9 * 10 * @version $Revision: 1. 5$ $Name: not supported by cvs2svn $11 * @date $Date: 2004-0 5-10 23:37:36$10 * @version $Revision: 1.6 $ $Name: not supported by cvs2svn $ 11 * @date $Date: 2004-08-04 23:37:39 $ 12 12 * 13 13 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/sys/psTrace.c
r1137 r1385 9 9 * @author George Gusciora, MHPCC 10 10 * 11 * @version $Revision: 1.1 1$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-0 6-30 01:09:12$11 * @version $Revision: 1.12 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-08-04 23:37:39 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/sys/psType.h
r1360 r1385 10 10 * @author Ross Harman, MHPCC 11 11 * 12 * @version $Revision: 1.1 5$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-0 7-31 02:28:10$12 * @version $Revision: 1.16 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2004-08-04 23:37:39 $ 14 14 * 15 15 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 142 142 */ 143 143 typedef struct 144 {145 psElemType type; ///< Primitive type.146 psDimen dimen; ///< Dimensionality.147 }144 { 145 psElemType type; ///< Primitive type. 146 psDimen dimen; ///< Dimensionality. 147 } 148 148 psType; 149 149 -
trunk/psLib/src/sysUtils/psAbort.c
r1138 r1385 9 9 * @author Eric Van Alst, MHPCC 10 10 * 11 * @version $Revision: 1. 5$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-0 6-30 01:17:20$11 * @version $Revision: 1.6 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-08-04 23:37:39 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/sysUtils/psError.c
r1138 r1385 10 10 * @author Eric Van Alst, MHPCC 11 11 * 12 * @version $Revision: 1. 7$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-0 6-30 01:17:20$12 * @version $Revision: 1.8 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2004-08-04 23:37:39 $ 14 14 * 15 15 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/sysUtils/psHash.c
r1375 r1385 10 10 * @author George Gusciora, MHPCC 11 11 * 12 * @version $Revision: 1.1 3$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-08-04 01:21:33$12 * @version $Revision: 1.14 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2004-08-04 23:37:39 $ 14 14 * 15 15 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 28 28 static void hashBucketFree( psHashBucket *bucket ); 29 29 static void *doHashWork( psHash* table, const char* key, void* data, bool remove 30 )31 ;30 ) 31 ; 32 32 static void hashFree( psHash *table ); 33 33 … … 45 45 psList *myLinkList = NULL; // The output data structure 46 46 psHashBucket *ptr = NULL; // Used to step thru linked list. 47 47 48 48 if ( table == NULL ) { 49 return NULL;50 }51 49 return NULL; 50 } 51 52 52 // Create the linked list 53 53 myLinkList = psListAlloc( NULL ); 54 54 55 55 // Loop through every bucket in the hash table. If that bucket is not 56 56 // NULL, then add the bucket's key to the linked list. 57 57 for ( i = 0;i < table->nbucket;i++ ) { 58 if ( table->buckets[ i ] != NULL ) { 59 // Since a bucket contains a linked list of keys/data, we must 60 // step trough each key in that linked list: 61 62 ptr = table->buckets[ i ]; 63 while ( ptr != NULL ) { 64 psListAdd( myLinkList, ptr->key, PS_LIST_HEAD ); 65 ptr = ptr->next; 66 } 67 } 58 if ( table->buckets[ i ] != NULL ) { 59 // Since a bucket contains a linked list of keys/data, we must 60 // step trough each key in that linked list: 61 62 ptr = table->buckets[ i ]; 63 while ( ptr != NULL ) { 64 psListAdd( myLinkList, ptr->key, PS_LIST_HEAD ); 65 ptr = ptr->next; 66 } 68 67 } 69 68 } 69 70 70 // Return the linked list 71 71 return ( myLinkList ); … … 89 89 { 90 90 if ( key == NULL ) { 91 psAbort( __func__, "psHashBucket() called with NULL key." );92 }93 91 psAbort( __func__, "psHashBucket() called with NULL key." ); 92 } 93 94 94 // Allocate memory for the new hash bucket. 95 95 psHashBucket *bucket = psAlloc( sizeof( psHashBucket ) ); 96 96 p_psMemSetDeallocator( bucket, ( psFreeFcn ) hashBucketFree ); 97 97 98 98 // Initialize the bucket. 99 99 bucket->key = psStringCopy( key ); 100 100 101 101 if ( data == NULL ) { 102 // NOTE: Should we flag a warning message?103 bucket->data = NULL;104 } else {105 bucket->data = psMemIncrRefCounter( data );106 }107 102 // NOTE: Should we flag a warning message? 103 bucket->data = NULL; 104 } else { 105 bucket->data = psMemIncrRefCounter( data ); 106 } 107 108 108 bucket->next = next; 109 109 110 110 return bucket; 111 111 } … … 123 123 { 124 124 if ( bucket == NULL ) { 125 return ;126 }127 125 return ; 126 } 127 128 128 // A bucket is actually a linked list of buckets. We recursively step 129 129 // through that linked list, free each bucket. 130 130 psFree( bucket->next ); 131 131 132 132 psFree( bucket->key ); 133 133 134 134 psFree( bucket->data ); 135 135 } … … 150 150 psHash *table = psAlloc( sizeof( psHash ) ); 151 151 p_psMemSetDeallocator( table, ( psFreeFcn ) hashFree ); 152 152 153 153 // Allocate memory for the buckets. 154 154 table->buckets = psAlloc( nbucket * sizeof( psHashBucket * ) ); 155 155 table->nbucket = nbucket; 156 156 157 157 psTrace( "utils.hash", 1, "Creating %d-element hash table\n", nbucket ); 158 158 159 159 // Initialize all buckets to NULL. 160 160 for ( i = 0; i < nbucket; i++ ) 161 {162 table->buckets[ i ] = NULL;163 }164 161 { 162 table->buckets[ i ] = NULL; 163 } 164 165 165 // Return the new hash table. 166 166 return table; … … 182 182 { 183 183 int i = 0; // Loop index variable. 184 184 185 185 if ( table == NULL ) { 186 return ;187 }188 186 return ; 187 } 188 189 189 // Loop through each bucket in the hash table. If that bucket is not 190 190 // NULL, then free the bucket via a function call to hashBucketFree(); 191 191 for ( i = 0; i < table->nbucket; i++ ) { 192 193 // A bucket is composed of a linked list of buckets. 194 if ( table->buckets[ i ] != NULL ) { 195 psFree( table->buckets[ i ] ); 196 } 192 193 // A bucket is composed of a linked list of buckets. 194 if ( table->buckets[ i ] != NULL ) { 195 psFree( table->buckets[ i ] ); 197 196 } 198 197 } 198 199 199 // Free the bucket structure, then the hash table. 200 200 psFree( table->buckets ); … … 221 221 *****************************************************************************/ 222 222 static void *doHashWork( psHash *table, const char *key, void *data, bool remove 223 )223 ) 224 224 { 225 225 long int hash = 1; // This will contain an integer value … … 229 229 psHashBucket *optr = NULL; // "original pointer": used to step 230 230 // thru the linked list for a bucket. 231 231 232 232 // The following condition should never be true, since this is a private 233 233 // function, but I'm checking it anyway since future coders might change 234 234 // the way this procedure is called. 235 235 if ( ( table == NULL ) || ( key == NULL ) ) { 236 237 psAbort( __func__, "psHashRemove() called with NULL key or table." );238 }239 236 237 psAbort( __func__, "psHashRemove() called with NULL key or table." ); 238 } 239 240 240 // NOTE: This is the originally supplied hash function. 241 241 // for (int i = 0, len = strlen(key); i < len; i++) { … … 243 243 // } 244 244 // hash &= (table->nbucket - 1); 245 245 246 246 // This hash algorithm is from Sedgewick. NOTE: must reread to ensure that 247 247 // the size of the hash table is not required to be a prime number. 248 248 tmpchar = ( char * ) key; 249 249 for ( hash = 0; *tmpchar != '\0'; tmpchar++ ) { 250 hash = ( 64 * hash + *tmpchar ) % ( table->nbucket );251 }252 250 hash = ( 64 * hash + *tmpchar ) % ( table->nbucket ); 251 } 252 253 253 // NOTE: This should not be necessary, but for now, I'm checking bounds 254 254 // anyway. 255 255 if ( ( hash < 0 ) || ( hash >= table->nbucket ) ) { 256 psAbort( __func__, "Internal hash function out of range (%d)", hash );257 }258 256 psAbort( __func__, "Internal hash function out of range (%d)", hash ); 257 } 258 259 259 // ptr will have the correct hash bucket. 260 260 ptr = table->buckets[ hash ]; 261 261 262 262 // We know the correct hash bucket, now we need to know what to do. 263 263 // If the data parameter is NULL, then, by definition, this is a retrieve 264 264 // or a remove operation on the hash table. 265 265 266 266 if ( data == NULL ) { 267 if ( remove267 if ( remove 268 268 ) { 269 // We search through the linked list for this bucket in 270 // the hash table and look for an entry for this key. 271 269 // We search through the linked list for this bucket in 270 // the hash table and look for an entry for this key. 271 272 optr = ptr; 273 while ( ptr != NULL ) { 274 // Dtermine if this entry holds the correct key. 275 if ( strcmp( key, ptr->key ) == 0 ) { 276 // The following lines of code are fairly standard ways 277 // of removing an item from a single-linked list. 278 279 void * data = ptr->data; 280 optr->next = ptr->next; 281 if ( ptr == table->buckets[ hash ] ) { 282 table->buckets[ hash ] = ptr->next; 283 } 284 285 psFree( ptr ); 286 287 // By definition, the data associated with that key 288 // must be returned, not freed. 289 return data; 290 } 272 291 optr = ptr; 273 while ( ptr != NULL ) {274 // Dtermine if this entry holds the correct key.275 if ( strcmp( key, ptr->key ) == 0 ) {276 // The following lines of code are fairly standard ways277 // of removing an item from a single-linked list.278 279 void * data = ptr->data;280 optr->next = ptr->next;281 if ( ptr == table->buckets[ hash ] ) {282 table->buckets[ hash ] = ptr->next;283 }284 285 psFree( ptr );286 287 // By definition, the data associated with that key288 // must be returned, not freed.289 return data;290 }291 optr = ptr;292 ptr = ptr->next;293 }294 return NULL; // not in hash295 }296 else {297 // If we get here, then a retrieve operation is requested. So,298 // we step trough the linked list at this bucket, and return the299 // data once we find it, or return NULL if we don't.300 while ( ptr != NULL ) {301 if ( strcmp( key, ptr->key ) == 0 ) {302 return ptr->data;303 }304 ptr = ptr->next;305 }306 return NULL; // not in hash307 }308 } else {309 // We get here if this procedure was called with non-NULL data.310 // Therefore, we should insert that data into the hash table.311 // First, we search through the linked list for this bucket in312 // the hash table and look for a duplicate entry for this key.313 314 while ( ptr != NULL ) {315 if ( strcmp( key, ptr->key ) == 0 ) {316 // We have found this key in the hash table.317 318 psTrace( "utils.hash.insert", 3, "Replacing data for %s\n",319 key );320 321 // NOTE: I have changed this behavior from the originally322 // supplied code. Formerly, if itemFree was NULL, then323 // the new data was not inserted into the hash table.324 325 psFree( ptr->data );326 327 ptr->data = psMemIncrRefCounter( data );328 return data;329 }330 292 ptr = ptr->next; 331 293 } 332 // We did not found key in the linked list for this bucket of the hash 333 // table. So, we insert this data at the head of that linked list. 334 335 table->buckets[ hash ] = hashBucketAlloc( key, 336 data, 337 table->buckets[ hash ] ); 338 return data; 294 return NULL; // not in hash 295 } 296 else { 297 // If we get here, then a retrieve operation is requested. So, 298 // we step trough the linked list at this bucket, and return the 299 // data once we find it, or return NULL if we don't. 300 while ( ptr != NULL ) { 301 if ( strcmp( key, ptr->key ) == 0 ) { 302 return ptr->data; 303 } 304 ptr = ptr->next; 305 } 306 return NULL; // not in hash 339 307 } 308 } else { 309 // We get here if this procedure was called with non-NULL data. 310 // Therefore, we should insert that data into the hash table. 311 // First, we search through the linked list for this bucket in 312 // the hash table and look for a duplicate entry for this key. 313 314 while ( ptr != NULL ) { 315 if ( strcmp( key, ptr->key ) == 0 ) { 316 // We have found this key in the hash table. 317 318 psTrace( "utils.hash.insert", 3, "Replacing data for %s\n", 319 key ); 320 321 // NOTE: I have changed this behavior from the originally 322 // supplied code. Formerly, if itemFree was NULL, then 323 // the new data was not inserted into the hash table. 324 325 psFree( ptr->data ); 326 327 ptr->data = psMemIncrRefCounter( data ); 328 return data; 329 } 330 ptr = ptr->next; 331 } 332 // We did not found key in the linked list for this bucket of the hash 333 // table. So, we insert this data at the head of that linked list. 334 335 table->buckets[ hash ] = hashBucketAlloc( key, 336 data, 337 table->buckets[ hash ] ); 338 return data; 339 } 340 340 } 341 341 … … 354 354 { 355 355 if ( table == NULL ) { 356 psAbort( __func__, "psHashInsert() called with NULL hash table." );357 }356 psAbort( __func__, "psHashInsert() called with NULL hash table." ); 357 } 358 358 if ( key == NULL ) { 359 psAbort( __func__, "psHashInsert() called with NULL key." );360 }359 psAbort( __func__, "psHashInsert() called with NULL key." ); 360 } 361 361 if ( data == NULL ) { 362 psAbort( __func__, "psHashLookup() called with NULL data." );363 }364 362 psAbort( __func__, "psHashLookup() called with NULL data." ); 363 } 364 365 365 return ( doHashWork( table, key, data, 0 ) != NULL ); 366 366 } … … 381 381 { 382 382 if ( table == NULL ) { 383 psAbort( __func__, "psHashLookup() called with NULL hash table." );384 }383 psAbort( __func__, "psHashLookup() called with NULL hash table." ); 384 } 385 385 if ( key == NULL ) { 386 psAbort( __func__, "psHashLookup() called with NULL key." );387 }388 389 386 psAbort( __func__, "psHashLookup() called with NULL key." ); 387 } 388 389 390 390 return doHashWork( table, key, NULL, 0 ); 391 391 } … … 405 405 void * data = NULL; 406 406 bool retVal = false; 407 407 408 408 if ( table == NULL ) { 409 psAbort( __func__, "psHashRemove() called with NULL hash table." );410 }409 psAbort( __func__, "psHashRemove() called with NULL hash table." ); 410 } 411 411 if ( key == NULL ) { 412 psAbort( __func__, "psHashRemove() called with NULL key." );413 }414 412 psAbort( __func__, "psHashRemove() called with NULL key." ); 413 } 414 415 415 data = doHashWork( table, key, NULL, 1 ); 416 416 if ( data != NULL ) { 417 psFree( data );418 retVal = true;419 } else {420 retVal = false;421 }417 psFree( data ); 418 retVal = true; 419 } else { 420 retVal = false; 421 } 422 422 return retVal; 423 423 } -
trunk/psLib/src/sysUtils/psHash.h
r1301 r1385 10 10 * @author George Gusciora, MHPCC 11 11 * 12 * @version $Revision: 1.1 6$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-0 7-27 23:09:23$12 * @version $Revision: 1.17 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2004-08-04 23:37:39 $ 14 14 * 15 15 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/sysUtils/psLogMsg.c
r1153 r1385 11 11 * @author George Gusciora, MHPCC 12 12 * 13 * @version $Revision: 1.2 0$ $Name: not supported by cvs2svn $14 * @date $Date: 2004-0 6-30 20:22:37$13 * @version $Revision: 1.21 $ $Name: not supported by cvs2svn $ 14 * @date $Date: 2004-08-04 23:37:39 $ 15 15 * 16 16 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 132 132 psError(__func__,"The location, %s, for protocol 'dest' is invalid.",location); 133 133 return 1; 134 } else if (strcmp(protocol,"file") == 0) { 135 FILE* file = fopen(location,"w"); 136 if (file == NULL) { 137 psError(__func__,"Could not open file '%s' for output.",location); 138 return 1; 139 } 140 if (logDest != NULL && logDest != stderr && logDest != stdout) { 141 fclose(logDest); 142 } 143 logDest = file; 144 return 0; 145 } 134 } else 135 if (strcmp(protocol,"file") == 0) { 136 FILE* file = fopen(location,"w"); 137 if (file == NULL) { 138 psError(__func__,"Could not open file '%s' for output.",location); 139 return 1; 140 } 141 if (logDest != NULL && logDest != stderr && logDest != stdout) { 142 fclose(logDest); 143 } 144 logDest = file; 145 return 0; 146 } 146 147 147 148 psError(__func__,"Do not know how to handle the protocol '%s'.",protocol); … … 336 337 if (head_ptr > head) { 337 338 *head_ptr++ = '|'; 338 } else if (!logMsg) { // no output desired 339 return; 340 } 339 } else 340 if (!logMsg) { // no output desired 341 return; 342 } 341 343 *head_ptr = '\0'; 342 344 -
trunk/psLib/src/sysUtils/psLogMsg.h
r1153 r1385 11 11 * @author George Gusciora, MHPCC 12 12 * 13 * @version $Revision: 1.1 0$ $Name: not supported by cvs2svn $14 * @date $Date: 2004-0 6-30 20:22:37$13 * @version $Revision: 1.11 $ $Name: not supported by cvs2svn $ 14 * @date $Date: 2004-08-04 23:37:39 $ 15 15 * 16 16 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/sysUtils/psMemory.c
r1360 r1385 8 8 * @author Robert Lupton, Princeton University 9 9 * 10 * @version $Revision: 1.3 0$ $Name: not supported by cvs2svn $11 * @date $Date: 2004-0 7-31 02:28:10$10 * @version $Revision: 1.31 $ $Name: not supported by cvs2svn $ 11 * @date $Date: 2004-08-04 23:37:39 $ 12 12 * 13 13 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 47 47 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL 48 48 }; 49 49 50 50 #ifdef PS_MEM_DEBUG 51 51 static psMemBlock* deadBlockList; // a place to put dead memBlocks in debug mode. … … 62 62 { 63 63 void * ptr = NULL; 64 64 65 65 pthread_mutex_lock( &recycleMemBlockListMutex ); 66 66 int level = recycleBins - 1; 67 67 while ( level >= 0 && ptr == NULL ) { 68 while ( recycleMemBlockList[ level ] != NULL && ptr == NULL ) {69 psMemBlock * old = recycleMemBlockList[ level ];70 recycleMemBlockList[ level ] = recycleMemBlockList[ level ] ->nextBlock;71 free( old );72 ptr = malloc( size );73 }74 level--;75 }68 while ( recycleMemBlockList[ level ] != NULL && ptr == NULL ) { 69 psMemBlock * old = recycleMemBlockList[ level ]; 70 recycleMemBlockList[ level ] = recycleMemBlockList[ level ] ->nextBlock; 71 free( old ); 72 ptr = malloc( size ); 73 } 74 level--; 75 } 76 76 pthread_mutex_unlock( &recycleMemBlockListMutex ); 77 77 78 78 return ptr; 79 79 } … … 84 84 { 85 85 psMemExhaustedCallback old = memExhaustedCallback; 86 86 87 87 if ( func != NULL ) { 88 memExhaustedCallback = func;89 } else {90 memExhaustedCallback = memExhaustedCallbackDefault;91 }92 88 memExhaustedCallback = func; 89 } else { 90 memExhaustedCallback = memExhaustedCallbackDefault; 91 } 92 93 93 return old; 94 94 } … … 98 98 { 99 99 if ( ptr->refCounter < 1 ) { 100 psError( __func__,101 "Block %ld allocated at %s:%d freed more than once at %s:%d\n",102 ptr->id, ptr->file, ptr->lineno, file, lineno );103 }104 100 psError( __func__, 101 "Block %ld allocated at %s:%d freed more than once at %s:%d\n", 102 ptr->id, ptr->file, ptr->lineno, file, lineno ); 103 } 104 105 105 if ( lineno > 0 ) { 106 psAbort( __func__, "Detected a problem in the memory system at %s:%d", file, lineno );107 }106 psAbort( __func__, "Detected a problem in the memory system at %s:%d", file, lineno ); 107 } 108 108 } 109 109 static psMemProblemCallback memProblemCallback = memProblemCallbackDefault; … … 112 112 { 113 113 psMemProblemCallback old = memProblemCallback; 114 114 115 115 if ( func != NULL ) { 116 memProblemCallback = func;117 } else {118 memProblemCallback = memProblemCallbackDefault;119 }120 116 memProblemCallback = func; 117 } else { 118 memProblemCallback = memProblemCallbackDefault; 119 } 120 121 121 return old; 122 122 } … … 133 133 psMemoryId old = p_psMemAllocateID; 134 134 p_psMemAllocateID = id; 135 135 136 136 return old; 137 137 } … … 141 141 psMemoryId old = p_psMemFreeID; 142 142 p_psMemFreeID = id; 143 143 144 144 return old; 145 145 } … … 154 154 { 155 155 static psMemoryId incr = 0; // "p_psMemAllocateID += incr" 156 156 157 157 return incr; 158 158 } … … 161 161 { 162 162 static psMemoryId incr = 0; // "p_psMemFreeID += incr" 163 163 164 164 return incr; 165 165 } … … 174 174 { 175 175 psMemFreeCallback old = memAllocateCallback; 176 176 177 177 if ( func != NULL ) { 178 memAllocateCallback = func;179 } else {180 memAllocateCallback = memAllocateCallbackDefault;181 }182 178 memAllocateCallback = func; 179 } else { 180 memAllocateCallback = memAllocateCallbackDefault; 181 } 182 183 183 return old; 184 184 } … … 187 187 { 188 188 psMemFreeCallback old = memFreeCallback; 189 189 190 190 if ( func != NULL ) { 191 memFreeCallback = func;192 } else {193 memFreeCallback = memFreeCallbackDefault;194 }195 191 memFreeCallback = func; 192 } else { 193 memFreeCallback = memFreeCallbackDefault; 194 } 195 196 196 return old; 197 197 } … … 206 206 id = memid + 1; 207 207 pthread_mutex_unlock( &memIdMutex ); 208 208 209 209 return id; 210 210 } … … 220 220 // n.b. since this is called by psMemCheckCorruption while the memblock list is mutex locked, 221 221 // we shouldn't call such things as p_psAlloc/p_psFree here. 222 222 223 223 if ( m == NULL ) { 224 psError( funcName, "Memory Corruption: NULL memory block found." );225 return 1;226 }227 224 psError( funcName, "Memory Corruption: NULL memory block found." ); 225 return 1; 226 } 227 228 228 if ( m->refCounter == 0 ) { 229 // using an unreferenced block of memory, are you?230 psError( __func__, "Memory Corruption: memory block %ld was freed but still used.",231 m->id );232 return 1;233 }234 229 // using an unreferenced block of memory, are you? 230 psError( __func__, "Memory Corruption: memory block %ld was freed but still used.", 231 m->id ); 232 return 1; 233 } 234 235 235 if ( m->startblock != P_PS_MEMMAGIC || m->endblock != P_PS_MEMMAGIC ) { 236 psError( funcName, "Memory Corruption: memory block %ld is corrupted (buffer underflow)",237 m->id );238 return 1;239 }236 psError( funcName, "Memory Corruption: memory block %ld is corrupted (buffer underflow)", 237 m->id ); 238 return 1; 239 } 240 240 if ( *( void** ) ( ( int8_t* ) ( m + 1 ) + m->userMemorySize ) != P_PS_MEMMAGIC ) { 241 psError( funcName, "Memory Corruption: memory block %ld is corrupted (buffer overflow)",242 m->id );243 return 1;244 }245 241 psError( funcName, "Memory Corruption: memory block %ld is corrupted (buffer overflow)", 242 m->id ); 243 return 1; 244 } 245 246 246 return 0; 247 247 } … … 250 250 { 251 251 int nbad = 0; // number of bad blocks 252 252 253 253 // get exclusive access to the memBlock list to avoid it changing on us while we use it. 254 254 pthread_mutex_lock( &memBlockListMutex ); 255 255 256 256 for ( psMemBlock * iter = lastMemBlockAllocated; iter != NULL; iter = iter->nextBlock ) { 257 if ( checkMemBlock( iter, __func__ ) ) {258 nbad++;259 260 memProblemCallback( iter, __func__, __LINE__ );261 262 if ( abort_on_error ) {263 // release the lock on the memblock list264 pthread_mutex_unlock( &memBlockListMutex );265 psAbort( __func__, "Detected memory corruption" );266 return nbad;267 }268 }269 }270 257 if ( checkMemBlock( iter, __func__ ) ) { 258 nbad++; 259 260 memProblemCallback( iter, __func__, __LINE__ ); 261 262 if ( abort_on_error ) { 263 // release the lock on the memblock list 264 pthread_mutex_unlock( &memBlockListMutex ); 265 psAbort( __func__, "Detected memory corruption" ); 266 return nbad; 267 } 268 } 269 } 270 271 271 // release the lock on the memblock list 272 272 pthread_mutex_unlock( &memBlockListMutex ); … … 278 278 279 279 psMemBlock * ptr = NULL; 280 280 281 281 // memory is of the size I want to bother recycling? 282 282 if ( size < P_PS_LARGE_BLOCK_SIZE ) { 283 // find the bin we need. 284 int level = 0; 285 while ( size > recycleBinSize[ level ] ) { 286 level++; 283 // find the bin we need. 284 int level = 0; 285 while ( size > recycleBinSize[ level ] ) { 286 level++; 287 } 288 // Are we in one of the bins 289 if ( level < recycleBins ) { 290 291 size = recycleBinSize[ level ]; // round-up size to next sized bin. 292 293 pthread_mutex_lock( &recycleMemBlockListMutex ); 294 295 if ( recycleMemBlockList[ level ] != NULL ) { 296 ptr = recycleMemBlockList[ level ]; 297 recycleMemBlockList[ level ] = ptr->nextBlock; 298 if ( recycleMemBlockList[ level ] != NULL ) { 299 recycleMemBlockList[ level ] ->previousBlock = NULL; 287 300 } 288 // Are we in one of the bins 289 if ( level < recycleBins ) { 290 291 size = recycleBinSize[ level ]; // round-up size to next sized bin. 292 293 pthread_mutex_lock( &recycleMemBlockListMutex ); 294 295 if ( recycleMemBlockList[ level ] != NULL ) { 296 ptr = recycleMemBlockList[ level ]; 297 recycleMemBlockList[ level ] = ptr->nextBlock; 298 if ( recycleMemBlockList[ level ] != NULL ) { 299 recycleMemBlockList[ level ] ->previousBlock = NULL; 300 } 301 size = ptr->userMemorySize; 302 } 303 304 pthread_mutex_unlock( &recycleMemBlockListMutex ); 305 } 306 } 307 301 size = ptr->userMemorySize; 302 } 303 304 pthread_mutex_unlock( &recycleMemBlockListMutex ); 305 } 306 } 307 308 308 if ( ptr == NULL ) { 309 ptr = malloc( sizeof( psMemBlock ) + size + sizeof( void* ) ); 310 309 ptr = malloc( sizeof( psMemBlock ) + size + sizeof( void* ) ); 310 311 if ( ptr == NULL ) { 312 ptr = memExhaustedCallback( size ); 311 313 if ( ptr == NULL ) { 312 ptr = memExhaustedCallback( size ); 313 if ( ptr == NULL ) { 314 psAbort( __func__, "Failed to allocate %u bytes at %s:%d", 315 size, file, lineno ); 316 } 317 } 318 319 ptr->startblock = P_PS_MEMMAGIC; 320 ptr->endblock = P_PS_MEMMAGIC; 321 ptr->userMemorySize = size; 322 pthread_mutex_init( &ptr->refCounterMutex, NULL ); 323 } 324 314 psAbort( __func__, "Failed to allocate %u bytes at %s:%d", 315 size, file, lineno ); 316 } 317 } 318 319 ptr->startblock = P_PS_MEMMAGIC; 320 ptr->endblock = P_PS_MEMMAGIC; 321 ptr->userMemorySize = size; 322 pthread_mutex_init( &ptr->refCounterMutex, NULL ); 323 } 324 325 325 // increment the memory id safely. 326 326 pthread_mutex_lock( &memBlockListMutex ); 327 327 *( psMemoryId* ) & ptr->id = ++memid; 328 328 pthread_mutex_unlock( &memBlockListMutex ); 329 329 330 330 ptr->file = file; 331 331 ptr->freeFcn = NULL; … … 333 333 *( void** ) ( ( int8_t* ) ( ptr + 1 ) + size ) = P_PS_MEMMAGIC; 334 334 ptr->previousBlock = NULL; 335 335 336 336 ptr->refCounter = 1; // one user so far 337 337 338 338 // need exclusive access of the memory block list now... 339 339 pthread_mutex_lock( &memBlockListMutex ); 340 340 341 341 // insert the new block to the front of the memBlock linked-list 342 342 ptr->nextBlock = lastMemBlockAllocated; 343 343 if ( ptr->nextBlock != NULL ) { 344 ptr->nextBlock->previousBlock = ptr;345 }344 ptr->nextBlock->previousBlock = ptr; 345 } 346 346 lastMemBlockAllocated = ptr; 347 347 348 348 pthread_mutex_unlock( &memBlockListMutex ); 349 349 350 350 // Did the user ask to be informed about this allocation? 351 351 if ( ptr->id == p_psMemAllocateID ) { 352 p_psMemAllocateID += memAllocateCallback( ptr );353 }354 352 p_psMemAllocateID += memAllocateCallback( ptr ); 353 } 354 355 355 // And return the user the memory that they allocated 356 356 return ptr + 1; // user memory … … 360 360 { 361 361 if ( vptr == NULL ) { 362 return p_psAlloc( size, file, lineno );363 } else {364 psMemBlock *ptr = ( ( psMemBlock * ) vptr ) - 1;365 bool isBlockLast = false;366 367 if ( checkMemBlock( ptr, __func__ ) != 0 ) {368 memProblemCallback( ptr, file, lineno );369 psAbort( file, "Realloc detected a memory corruption (id %ld @ %s:%d).",370 ptr->id, ptr->file, ptr->lineno );371 }372 373 pthread_mutex_lock( &memBlockListMutex );374 375 isBlockLast = ( ptr == lastMemBlockAllocated );376 377 ptr = ( psMemBlock* ) realloc( ptr, sizeof( psMemBlock ) + size + sizeof( void* ) );378 379 if ( ptr == NULL ) {380 psAbort( __func__, "Failed to reallocate %ld bytes at %s:%d",381 size, file, lineno );382 }383 384 ptr->userMemorySize = size;385 *( void** ) ( ( int8_t* ) ( ptr + 1 ) + size ) = P_PS_MEMMAGIC;386 387 if ( isBlockLast ) {388 lastMemBlockAllocated = ptr;389 }390 391 // the block location may have changed, so fix the linked list addresses.392 if ( ptr->nextBlock != NULL ) {393 ptr->nextBlock->previousBlock = ptr;394 }395 if ( ptr->previousBlock != NULL ) {396 ptr->previousBlock->nextBlock = ptr;397 }398 399 pthread_mutex_unlock( &memBlockListMutex );400 401 // Did the user ask to be informed about this allocation?402 if ( ptr->id == p_psMemAllocateID ) {403 p_psMemAllocateID += memAllocateCallback( ptr );404 }405 406 return ptr + 1; // usr memory407 }362 return p_psAlloc( size, file, lineno ); 363 } else { 364 psMemBlock *ptr = ( ( psMemBlock * ) vptr ) - 1; 365 bool isBlockLast = false; 366 367 if ( checkMemBlock( ptr, __func__ ) != 0 ) { 368 memProblemCallback( ptr, file, lineno ); 369 psAbort( file, "Realloc detected a memory corruption (id %ld @ %s:%d).", 370 ptr->id, ptr->file, ptr->lineno ); 371 } 372 373 pthread_mutex_lock( &memBlockListMutex ); 374 375 isBlockLast = ( ptr == lastMemBlockAllocated ); 376 377 ptr = ( psMemBlock* ) realloc( ptr, sizeof( psMemBlock ) + size + sizeof( void* ) ); 378 379 if ( ptr == NULL ) { 380 psAbort( __func__, "Failed to reallocate %ld bytes at %s:%d", 381 size, file, lineno ); 382 } 383 384 ptr->userMemorySize = size; 385 *( void** ) ( ( int8_t* ) ( ptr + 1 ) + size ) = P_PS_MEMMAGIC; 386 387 if ( isBlockLast ) { 388 lastMemBlockAllocated = ptr; 389 } 390 391 // the block location may have changed, so fix the linked list addresses. 392 if ( ptr->nextBlock != NULL ) { 393 ptr->nextBlock->previousBlock = ptr; 394 } 395 if ( ptr->previousBlock != NULL ) { 396 ptr->previousBlock->nextBlock = ptr; 397 } 398 399 pthread_mutex_unlock( &memBlockListMutex ); 400 401 // Did the user ask to be informed about this allocation? 402 if ( ptr->id == p_psMemAllocateID ) { 403 p_psMemAllocateID += memAllocateCallback( ptr ); 404 } 405 406 return ptr + 1; // usr memory 407 } 408 408 } 409 409 … … 421 421 int j = 0; 422 422 psMemBlock* topBlock = lastMemBlockAllocated; 423 423 424 424 pthread_mutex_lock( &memBlockListMutex ); 425 425 426 426 for ( psMemBlock * iter = topBlock; iter != NULL; iter = iter->nextBlock ) { 427 if ( ( psMemGetRefCounter( iter + 1 ) > 0 ) && ( iter->id >= id0 ) ) { 428 nleak++; 429 430 if ( fd != NULL ) { 431 if ( nleak == 1 ) { 432 fprintf( fd, " %20s:line ID\n", "file" ); 433 } 434 435 fprintf( fd, " %20s:%-4d %ld\n", iter->file, iter->lineno, iter->id ); 436 } 427 if ( ( psMemGetRefCounter( iter + 1 ) > 0 ) && ( iter->id >= id0 ) ) { 428 nleak++; 429 430 if ( fd != NULL ) { 431 if ( nleak == 1 ) { 432 fprintf( fd, " %20s:line ID\n", "file" ); 437 433 } 438 } 439 434 435 fprintf( fd, " %20s:%-4d %ld\n", iter->file, iter->lineno, iter->id ); 436 } 437 } 438 } 439 440 440 pthread_mutex_unlock( &memBlockListMutex ); 441 441 442 442 if ( nleak == 0 || arr == NULL ) { 443 return nleak;444 }445 443 return nleak; 444 } 445 446 446 *arr = p_psAlloc( nleak * sizeof( psMemBlock ), __FILE__, __LINE__ ); 447 447 pthread_mutex_lock( &memBlockListMutex ); 448 448 449 449 for ( psMemBlock * iter = topBlock; iter != NULL; iter = iter->nextBlock ) { 450 if ( ( psMemGetRefCounter( iter + 1 ) > 0 ) && ( iter->id >= id0 ) ) {451 ( *arr ) [ j++ ] = iter;452 if ( j == nleak ) { // found them all453 break;454 }455 }456 }457 450 if ( ( psMemGetRefCounter( iter + 1 ) > 0 ) && ( iter->id >= id0 ) ) { 451 ( *arr ) [ j++ ] = iter; 452 if ( j == nleak ) { // found them all 453 break; 454 } 455 } 456 } 457 458 458 pthread_mutex_unlock( &memBlockListMutex ); 459 459 460 460 return nleak; 461 461 } … … 463 463 /* 464 464 * Reference counting APIs 465 */ 465 */ 466 466 // return refCounter 467 467 psReferenceCount psMemGetRefCounter( void *vptr ) … … 469 469 psMemBlock * ptr; 470 470 unsigned int refCount; 471 471 472 472 if ( vptr == NULL ) { 473 return 0;474 }475 473 return 0; 474 } 475 476 476 ptr = ( ( psMemBlock * ) vptr ) - 1; 477 477 478 478 if ( checkMemBlock( ptr, __func__ ) != 0 ) { 479 memProblemCallback( ptr, __func__, __LINE__ );480 }481 479 memProblemCallback( ptr, __func__, __LINE__ ); 480 } 481 482 482 pthread_mutex_lock( &ptr->refCounterMutex ); 483 483 refCount = ptr->refCounter; 484 484 pthread_mutex_unlock( &ptr->refCounterMutex ); 485 485 486 486 return refCount; 487 487 } … … 490 490 { 491 491 psMemBlock * ptr; 492 492 493 493 if ( vptr == NULL ) { 494 return vptr;495 }496 494 return vptr; 495 } 496 497 497 ptr = ( ( psMemBlock * ) vptr ) - 1; 498 498 499 499 if ( checkMemBlock( ptr, __func__ ) ) { 500 memProblemCallback( ptr, file, lineno );501 }502 500 memProblemCallback( ptr, file, lineno ); 501 } 502 503 503 pthread_mutex_lock( &ptr->refCounterMutex ); 504 504 ptr->refCounter++; 505 505 pthread_mutex_unlock( &ptr->refCounterMutex ); 506 506 507 507 return vptr; 508 508 } … … 512 512 { 513 513 if ( vptr == NULL ) { 514 return NULL;515 }516 514 return NULL; 515 } 516 517 517 psMemBlock *ptr = ( ( psMemBlock * ) vptr ) - 1; 518 518 519 519 if ( checkMemBlock( ptr, __func__ ) != 0 ) { 520 memProblemCallback( ptr, file, lineno );521 return NULL;522 }523 520 memProblemCallback( ptr, file, lineno ); 521 return NULL; 522 } 523 524 524 pthread_mutex_lock( &ptr->refCounterMutex ); 525 525 526 526 if ( ptr->refCounter > 1 ) { 527 /// XXX - Probably should have another mutex here. 528 ptr->refCounter--; // multiple references, just decrement the count. 529 pthread_mutex_unlock( &ptr->refCounterMutex ); 530 527 /// XXX - Probably should have another mutex here. 528 ptr->refCounter--; // multiple references, just decrement the count. 529 pthread_mutex_unlock( &ptr->refCounterMutex ); 530 531 } else { 532 pthread_mutex_unlock( &ptr->refCounterMutex ); 533 534 // Did the user ask to be informed about this deallocation? 535 if ( ptr->id == p_psMemFreeID ) { 536 p_psMemFreeID += memFreeCallback( ptr ); 537 } 538 539 if ( ptr->freeFcn != NULL ) { 540 ptr->freeFcn( vptr ); 541 } 542 543 pthread_mutex_lock( &memBlockListMutex ); 544 545 // cut the memBlock out of the memBlock list 546 if ( ptr->nextBlock != NULL ) { 547 ptr->nextBlock->previousBlock = ptr->previousBlock; 548 } 549 if ( ptr->previousBlock != NULL ) { 550 ptr->previousBlock->nextBlock = ptr->nextBlock; 551 } 552 if ( lastMemBlockAllocated == ptr ) { 553 lastMemBlockAllocated = ptr->nextBlock; 554 } 555 556 pthread_mutex_unlock( &memBlockListMutex ); 557 558 559 // do we need to recycle? 560 if ( ptr->userMemorySize < P_PS_LARGE_BLOCK_SIZE ) { 561 562 int level = 1; 563 while ( ptr->userMemorySize >= recycleBinSize[ level ] ) { 564 level++; 565 } 566 level--; 567 568 ptr->refCounter = 0; 569 ptr->previousBlock = NULL; 570 571 pthread_mutex_lock( &recycleMemBlockListMutex ); 572 ptr->nextBlock = recycleMemBlockList[ level ]; 573 if ( recycleMemBlockList[ level ] != NULL ) { 574 recycleMemBlockList[ level ] ->previousBlock = ptr; 575 } 576 recycleMemBlockList[ level ] = ptr; 577 pthread_mutex_unlock( &recycleMemBlockListMutex ); 578 531 579 } else { 532 pthread_mutex_unlock( &ptr->refCounterMutex ); 533 534 // Did the user ask to be informed about this deallocation? 535 if ( ptr->id == p_psMemFreeID ) { 536 p_psMemFreeID += memFreeCallback( ptr ); 537 } 538 539 if ( ptr->freeFcn != NULL ) { 540 ptr->freeFcn( vptr ); 541 } 542 543 pthread_mutex_lock( &memBlockListMutex ); 544 545 // cut the memBlock out of the memBlock list 546 if ( ptr->nextBlock != NULL ) { 547 ptr->nextBlock->previousBlock = ptr->previousBlock; 548 } 549 if ( ptr->previousBlock != NULL ) { 550 ptr->previousBlock->nextBlock = ptr->nextBlock; 551 } 552 if ( lastMemBlockAllocated == ptr ) { 553 lastMemBlockAllocated = ptr->nextBlock; 554 } 555 556 pthread_mutex_unlock( &memBlockListMutex ); 557 558 559 // do we need to recycle? 560 if ( ptr->userMemorySize < P_PS_LARGE_BLOCK_SIZE ) { 561 562 int level = 1; 563 while ( ptr->userMemorySize >= recycleBinSize[ level ] ) { 564 level++; 565 } 566 level--; 567 568 ptr->refCounter = 0; 569 ptr->previousBlock = NULL; 570 571 pthread_mutex_lock( &recycleMemBlockListMutex ); 572 ptr->nextBlock = recycleMemBlockList[ level ]; 573 if ( recycleMemBlockList[ level ] != NULL ) { 574 recycleMemBlockList[ level ] ->previousBlock = ptr; 575 } 576 recycleMemBlockList[ level ] = ptr; 577 pthread_mutex_unlock( &recycleMemBlockListMutex ); 578 579 } else { 580 // memory is larger than I want to recycle. 581 #ifdef PS_MEM_DEBUG 582 ( void ) p_psRealloc( vptr, 0, file, lineno ); 583 ptr->previousBlock = NULL; 584 ptr->nextBlock = deadBlockList; 585 if ( deadBlockList != NULL ) { 586 deadBlockList->previous = ptr; 587 } 588 deadBlockList = ptr; 589 #else 590 591 pthread_mutex_destroy( &ptr->refCounterMutex ); 592 free( ptr ); 593 #endif 594 595 } 596 597 vptr = NULL; // since we freed it, make sure we return NULL. 598 } 599 580 // memory is larger than I want to recycle. 581 #ifdef PS_MEM_DEBUG 582 ( void ) p_psRealloc( vptr, 0, file, lineno ); 583 ptr->previousBlock = NULL; 584 ptr->nextBlock = deadBlockList; 585 if ( deadBlockList != NULL ) { 586 deadBlockList->previous = ptr; 587 } 588 deadBlockList = ptr; 589 #else 590 591 pthread_mutex_destroy( &ptr->refCounterMutex ); 592 free( ptr ); 593 #endif 594 595 } 596 597 vptr = NULL; // since we freed it, make sure we return NULL. 598 } 599 600 600 return vptr; 601 601 } … … 604 604 { 605 605 if ( vptr == NULL ) { 606 return ;607 }608 606 return ; 607 } 608 609 609 psMemBlock *ptr = ( ( psMemBlock * ) vptr ) - 1; 610 610 611 611 if ( checkMemBlock( ptr, __func__ ) != 0 ) { 612 memProblemCallback( ptr, __func__, __LINE__ );613 }614 612 memProblemCallback( ptr, __func__, __LINE__ ); 613 } 614 615 615 ptr->freeFcn = freeFcn; 616 616 617 617 } 618 618 psFreeFcn p_psMemGetDeallocator( void* vptr ) 619 619 { 620 620 if ( vptr == NULL ) { 621 return NULL;622 }623 621 return NULL; 622 } 623 624 624 psMemBlock *ptr = ( ( psMemBlock * ) vptr ) - 1; 625 625 626 626 if ( checkMemBlock( ptr, __func__ ) != 0 ) { 627 memProblemCallback( ptr, __func__, __LINE__ );628 }629 627 memProblemCallback( ptr, __func__, __LINE__ ); 628 } 629 630 630 return ptr->freeFcn; 631 631 } -
trunk/psLib/src/sysUtils/psMemory.h
r1233 r1385 14 14 * @ingroup MemoryManagement 15 15 * 16 * @version $Revision: 1.2 1$ $Name: not supported by cvs2svn $17 * @date $Date: 2004-0 7-15 23:52:34$16 * @version $Revision: 1.22 $ $Name: not supported by cvs2svn $ 17 * @date $Date: 2004-08-04 23:37:39 $ 18 18 * 19 19 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/sysUtils/psString.c
r635 r1385 8 8 * @author Eric Van Alst, MHPCC 9 9 * 10 * @version $Revision: 1. 5$ $Name: not supported by cvs2svn $11 * @date $Date: 2004-0 5-10 23:37:36$10 * @version $Revision: 1.6 $ $Name: not supported by cvs2svn $ 11 * @date $Date: 2004-08-04 23:37:39 $ 12 12 * 13 13 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/sysUtils/psTrace.c
r1137 r1385 9 9 * @author George Gusciora, MHPCC 10 10 * 11 * @version $Revision: 1.1 1$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-0 6-30 01:09:12$11 * @version $Revision: 1.12 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-08-04 23:37:39 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/sysUtils/psType.h
r1360 r1385 10 10 * @author Ross Harman, MHPCC 11 11 * 12 * @version $Revision: 1.1 5$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-0 7-31 02:28:10$12 * @version $Revision: 1.16 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2004-08-04 23:37:39 $ 14 14 * 15 15 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 142 142 */ 143 143 typedef struct 144 {145 psElemType type; ///< Primitive type.146 psDimen dimen; ///< Dimensionality.147 }144 { 145 psElemType type; ///< Primitive type. 146 psDimen dimen; ///< Dimensionality. 147 } 148 148 psType; 149 149 -
trunk/psLib/src/types/psArray.c
r1228 r1385 8 8 * @author Ross Harman, MHPCC 9 9 * 10 * @version $Revision: 1. 9$ $Name: not supported by cvs2svn $11 * @date $Date: 2004-0 7-15 22:18:02$10 * @version $Revision: 1.10 $ $Name: not supported by cvs2svn $ 11 * @date $Date: 2004-08-04 23:37:39 $ 12 12 * 13 13 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 67 67 psError(__func__, "Null input vector\n"); 68 68 return NULL; 69 } else if(in->nalloc != nalloc) { // No need to realloc to same size 70 if(nalloc < in->n) { 71 for (int i = nalloc; i < in->n; i++) { // For reduction in vector size 72 psFree(in->data[i]); 69 } else 70 if(in->nalloc != nalloc) { // No need to realloc to same size 71 if(nalloc < in->n) { 72 for (int i = nalloc; i < in->n; i++) { // For reduction in vector size 73 psFree(in->data[i]); 74 } 75 in->n = nalloc; 73 76 } 74 in->n = nalloc; 77 78 // Realloc after decrementation to avoid accessing freed array elements 79 in->data = psRealloc(in->data,nalloc*sizeof(psPTR)); 80 in->nalloc = nalloc; 75 81 } 76 77 // Realloc after decrementation to avoid accessing freed array elements78 in->data = psRealloc(in->data,nalloc*sizeof(psPTR));79 in->nalloc = nalloc;80 }81 82 82 83 return in; -
trunk/psLib/src/types/psBitSet.c
r1172 r1385 10 10 * @author Ross Harman, MHPCC 11 11 * 12 * @version $Revision: 1.1 2$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-0 7-01 21:48:11$12 * @version $Revision: 1.13 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2004-08-04 23:37:39 $ 14 14 * 15 15 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 126 126 psError(__func__, " : Line %d - Null psBitSet for inBitSet argument", __LINE__); 127 127 return inBitSet; 128 } else if(bit < 0) { 129 psError(__func__, " : Line %d - Bit position too small: %d", __LINE__, bit); 130 return inBitSet; 131 } else if(bit > inBitSet->n*8-1) { 132 psError(__func__, " : Line %d - Bit position too large: %d", __LINE__, bit); 133 return inBitSet; 134 } 128 } else 129 if(bit < 0) { 130 psError(__func__, " : Line %d - Bit position too small: %d", __LINE__, bit); 131 return inBitSet; 132 } else 133 if(bit > inBitSet->n*8-1) { 134 psError(__func__, " : Line %d - Bit position too large: %d", __LINE__, bit); 135 return inBitSet; 136 } 135 137 136 138 // Variable byte is the byte in the array that contains the bit to be set … … 148 150 psError(__func__, " : Line %d - Null psBitSet for inBitSet argument", __LINE__); 149 151 return 0; 150 } else if(bit < 0) { 151 psError(__func__, " : Line %d - Bit position too small: %d", __LINE__, bit); 152 return 0; 153 } else if(bit > inBitSet->n*8-1) { 154 psError(__func__, " : Line %d - Bit position too large: %d", __LINE__, bit); 155 return 0; 156 } 152 } else 153 if(bit < 0) { 154 psError(__func__, " : Line %d - Bit position too small: %d", __LINE__, bit); 155 return 0; 156 } else 157 if(bit > inBitSet->n*8-1) { 158 psError(__func__, " : Line %d - Bit position too large: %d", __LINE__, bit); 159 return 0; 160 } 157 161 158 162 // Variable byte is the byte in the array that contains the bit to be tested -
trunk/psLib/src/types/psList.c
r1228 r1385 6 6 * @author Robert Daniel DeSonia, MHPCC 7 7 * 8 * @version $Revision: 1.1 1$ $Name: not supported by cvs2svn $9 * @date $Date: 2004-0 7-15 22:18:02$8 * @version $Revision: 1.12 $ $Name: not supported by cvs2svn $ 9 * @date $Date: 2004-08-04 23:37:39 $ 10 10 * 11 11 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 349 349 if (list->iter == ITER_INIT_HEAD) { 350 350 return list->head; 351 } else if (list->iter == ITER_INIT_TAIL) { 352 return list->tail; 353 } else { 354 return list->iter; 355 } 351 } else 352 if (list->iter == ITER_INIT_TAIL) { 353 return list->tail; 354 } else { 355 return list->iter; 356 } 356 357 } 357 358 … … 360 361 if (list->iter == ITER_INIT_HEAD) { 361 362 return 0; 362 } else if (list->iter == ITER_INIT_TAIL) { 363 return list->size-1; 364 } else { 365 return list->iterIndex; 366 } 363 } else 364 if (list->iter == ITER_INIT_TAIL) { 365 return list->size-1; 366 } else { 367 return list->iterIndex; 368 } 367 369 } 368 370 -
trunk/psLib/src/types/psMetadata.c
r1381 r1385 11 11 * @author Ross Harman, MHPCC 12 12 * 13 * @version $Revision: 1. 7$ $Name: not supported by cvs2svn $14 * @date $Date: 2004-08-04 2 1:05:24$13 * @version $Revision: 1.8 $ $Name: not supported by cvs2svn $ 14 * @date $Date: 2004-08-04 23:37:39 $ 15 15 * 16 16 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 65 65 { 66 66 psMetadataType type; 67 67 68 68 type = metadataItem->type; 69 69 70 70 if ( metadataItem == NULL ) { 71 return ;72 }73 71 return ; 72 } 73 74 74 psFree( metadataItem->name ); 75 75 psFree( metadataItem->comment ); 76 76 psFree( metadataItem->items ); 77 77 78 78 if ( type == PS_META_STR || 79 79 type == PS_META_IMG || … … 82 82 type == PS_META_ASTROM || 83 83 type == PS_META_UNKNOWN ) { 84 psFree( metadataItem->data.V );85 }84 psFree( metadataItem->data.V ); 85 } 86 86 } 87 87 … … 89 89 { 90 90 if ( metadata == NULL ) { 91 return ;92 }91 return ; 92 } 93 93 psFree( metadata->list ); 94 94 psFree( metadata->table ); … … 103 103 va_list argPtr; 104 104 psMetadataItem *metadataItem = NULL; 105 105 106 106 // Get the variable list parameters to pass to allocation function 107 107 va_start( argPtr, comment ); 108 108 109 109 // Call metadata item allocation 110 110 metadataItem = psMetadataItemAllocV( name, type, comment, argPtr ); 111 111 112 112 // Clean up stack after variable arguement has been used 113 113 va_end( argPtr ); 114 114 115 115 return metadataItem; 116 116 } … … 119 119 { 120 120 psMetadataItem * metadataItem = NULL; 121 121 122 122 if ( name == NULL ) { 123 psError( __func__, "Null value for string not allowed" );124 return NULL;125 }126 123 psError( __func__, "Null value for string not allowed" ); 124 return NULL; 125 } 126 127 127 // Allocate metadata item 128 128 metadataItem = ( psMetadataItem * ) psAlloc( sizeof( psMetadataItem ) ); 129 129 if ( metadataItem == NULL ) { 130 psAbort( __func__, "Failed to allocate memory" );131 }132 130 psAbort( __func__, "Failed to allocate memory" ); 131 } 132 133 133 // Set deallocator 134 134 p_psMemSetDeallocator( metadataItem, ( psFreeFcn ) metadataItemFree ); 135 135 136 136 // Allocate and set metadata item comment 137 137 metadataItem->comment = ( char * ) psAlloc( sizeof( char ) * MAX_STRING_LENGTH ); 138 138 if ( comment == NULL ) { 139 // Per SDRS, null isn't allowed, must use "" instead140 strncpy( metadataItem->comment, "", MAX_STRING_LENGTH );141 } else {142 strncpy( metadataItem->comment, comment, MAX_STRING_LENGTH );143 }144 139 // Per SDRS, null isn't allowed, must use "" instead 140 strncpy( metadataItem->comment, "", MAX_STRING_LENGTH ); 141 } else { 142 strncpy( metadataItem->comment, comment, MAX_STRING_LENGTH ); 143 } 144 145 145 // Set metadata item unique id 146 146 *( int* ) ( &metadataItem->id ) = ++metadataId; 147 147 148 148 // Set metadata item type 149 149 metadataItem->type = type; 150 150 151 151 // Set metadata item value 152 152 switch ( type ) { 153 case PS_META_BOOL:154 metadataItem->data.B = ( bool ) va_arg( argPtr, int );155 break;156 case PS_META_S32:157 metadataItem->data.S32 = va_arg( argPtr, psS32 );158 break;159 case PS_META_F32:160 metadataItem->data.F32 = ( psF32 ) va_arg( argPtr, psF64 );161 break;162 case PS_META_F64:163 metadataItem->data.F64 = va_arg( argPtr, psF64 );164 break;165 case PS_META_STR:166 metadataItem->data.V = psStringNCopy( va_arg( argPtr, char* ), MAX_STRING_LENGTH );167 break;168 case PS_META_IMG:169 case PS_META_JPEG:170 case PS_META_PNG:171 case PS_META_ASTROM:172 case PS_META_UNKNOWN:173 default:174 psError( __func__, "Invalid psMetadataType: %d", type );175 }176 153 case PS_META_BOOL: 154 metadataItem->data.B = ( bool ) va_arg( argPtr, int ); 155 break; 156 case PS_META_S32: 157 metadataItem->data.S32 = va_arg( argPtr, psS32 ); 158 break; 159 case PS_META_F32: 160 metadataItem->data.F32 = ( psF32 ) va_arg( argPtr, psF64 ); 161 break; 162 case PS_META_F64: 163 metadataItem->data.F64 = va_arg( argPtr, psF64 ); 164 break; 165 case PS_META_STR: 166 metadataItem->data.V = psStringNCopy( va_arg( argPtr, char* ), MAX_STRING_LENGTH ); 167 break; 168 case PS_META_IMG: 169 case PS_META_JPEG: 170 case PS_META_PNG: 171 case PS_META_ASTROM: 172 case PS_META_UNKNOWN: 173 default: 174 psError( __func__, "Invalid psMetadataType: %d", type ); 175 } 176 177 177 // Allocate and set metadata item name 178 178 metadataItem->name = ( char * ) psAlloc( sizeof( char ) * MAX_STRING_LENGTH ); 179 179 vsprintf( metadataItem->name, name, argPtr ); 180 180 181 181 // Allocate metadata items with same name. 182 182 metadataItem->items = psListAlloc( NULL ); 183 183 184 184 return metadataItem; 185 185 } … … 190 190 psHash *table = NULL; 191 191 psMetadata *metadata = NULL; 192 192 193 193 // Allocate metadata 194 194 metadata = ( psMetadata * ) psAlloc( sizeof( psMetadata ) ); 195 195 if ( metadata == NULL ) { 196 psAbort( __func__, "Failed to allocate metadata" );197 }198 196 psAbort( __func__, "Failed to allocate metadata" ); 197 } 198 199 199 // Set deallocator 200 200 p_psMemSetDeallocator( metadata, ( psFreeFcn ) metadataFree ); 201 201 202 202 // Allocate metadata's internal containers 203 203 list = ( psList * ) psListAlloc( NULL ); 204 204 if ( list == NULL ) { 205 psAbort( __func__, "Failed to allocate list" );206 }207 205 psAbort( __func__, "Failed to allocate list" ); 206 } 207 208 208 table = ( psHash * ) psHashAlloc( 10 ); 209 209 if ( table == NULL ) { 210 psAbort( __func__, "Failed to allocate table" );211 }212 210 psAbort( __func__, "Failed to allocate table" ); 211 } 212 213 213 metadata->list = list; 214 214 metadata->table = table; 215 215 216 216 return metadata; 217 217 } … … 224 224 psMetadataItem *value = NULL; 225 225 psMetadataType type = PS_META_ITEM_SET; 226 226 227 227 if ( md == NULL ) { 228 psError( __func__, "Null metadata collection not allowed" );229 return false;230 }231 228 psError( __func__, "Null metadata collection not allowed" ); 229 return false; 230 } 231 232 232 if ( metadataItem == NULL ) { 233 psError( __func__, "Null metadata item not allowed" );234 return false;235 }236 233 psError( __func__, "Null metadata item not allowed" ); 234 return false; 235 } 236 237 237 type = metadataItem->type; 238 238 239 239 mdTable = md->table; 240 240 if ( mdTable == NULL ) { 241 psError( __func__, "Null metadata table not allowed" );242 return false;243 }244 245 mdList = md->list; 246 if ( mdList == NULL ) { 247 psError( __func__, "Null metadata list not allowed" );248 return false;249 }250 241 psError( __func__, "Null metadata table not allowed" ); 242 return false; 243 } 244 245 mdList = md->list; 246 if ( mdList == NULL ) { 247 psError( __func__, "Null metadata list not allowed" ); 248 return false; 249 } 250 251 251 key = metadataItem->name; 252 252 if ( key == NULL ) { 253 psError( __func__, "Null key item not allowed" );254 return false;255 }256 253 psError( __func__, "Null key item not allowed" ); 254 return false; 255 } 256 257 257 // Check if key is already in table 258 258 value = ( psMetadataItem* ) psHashLookup( mdTable, key ); 259 259 if ( value != NULL && type != PS_META_ITEM_SET ) { 260 261 // The key was found and the new metadata item is a leaf node (its type isn't PS_META_ITEM_SET), so 262 // add the new metadata item to hash as a child of the existing metadata item folder node. 263 if ( !psListAdd( value->items, metadataItem, where ) ) { 264 psError( __func__, "Couldn't add metadata item to items list. Name: %s", 265 metadataItem->name ); 266 return false; 267 } 268 } else if ( value != NULL ) { 269 260 261 // The key was found and the new metadata item is a leaf node (its type isn't PS_META_ITEM_SET), so 262 // add the new metadata item to hash as a child of the existing metadata item folder node. 263 if ( !psListAdd( value->items, metadataItem, where ) ) { 264 psError( __func__, "Couldn't add metadata item to items list. Name: %s", 265 metadataItem->name ); 266 return false; 267 } 268 } else 269 if ( value != NULL ) { 270 270 271 // The key was found and the new metadata item is a folder node. Don't add new metadata item, since 271 272 // it will wipe out existing node. … … 274 275 return false; 275 276 } else { 276 277 277 278 // Duplicate key not found. Add new metadata item to metadata collection's hash 278 279 if ( !psHashAdd( mdTable, key, metadataItem ) ) { 279 psError( __func__, "Couldn't add metadata item to metadata collection table. Name: %s",280 metadataItem->name );281 return false;282 }283 } 284 280 psError( __func__, "Couldn't add metadata item to metadata collection table. Name: %s", 281 metadataItem->name ); 282 return false; 283 } 284 } 285 285 286 // Add all items to metadata collection's list, even if they have the same metadata item names 286 287 if ( !psListAdd( md->list, metadataItem, where ) ) { 287 psError( __func__, "Couldn't add metadata item to metadata collection list. Name: %s",288 metadataItem->name );289 return false;290 }291 288 psError( __func__, "Couldn't add metadata item to metadata collection list. Name: %s", 289 metadataItem->name ); 290 return false; 291 } 292 292 293 return true; 293 294 } … … 298 299 va_list argPtr; 299 300 psMetadataItem *metadataItem = NULL; 300 301 301 302 va_start( argPtr, comment ); 302 303 metadataItem = psMetadataItemAllocV( name, type, comment, argPtr ); 303 304 va_end( argPtr ); 304 305 305 306 if ( !psMetadataAddItem( md, where, metadataItem ) ) { 306 psError( __func__, "Couldn't add metadata item to metadata collection list. Name: %s",307 metadataItem->name );308 psFree( metadataItem );309 return false;310 }311 307 psError( __func__, "Couldn't add metadata item to metadata collection list. Name: %s", 308 metadataItem->name ); 309 psFree( metadataItem ); 310 return false; 311 } 312 312 313 // Decrement reference count, since the metadata item is now in metadata collection and no longer needed here 313 314 psMemDecrRefCounter( metadataItem ); 314 315 315 316 return true; 316 317 } … … 323 324 psMetadataItem *entry = NULL; 324 325 psMetadataItem *entryChild = NULL; 325 326 mdList = md->list; 327 if ( mdList == NULL ) { 328 psError( __func__, "Null metadata list not allowed" );329 return false;330 }331 326 327 mdList = md->list; 328 if ( mdList == NULL ) { 329 psError( __func__, "Null metadata list not allowed" ); 330 return false; 331 } 332 332 333 mdTable = md->table; 333 334 if ( mdTable == NULL ) { 334 psError( __func__, "Null metadata table not allowed" );335 return false;336 }337 335 psError( __func__, "Null metadata table not allowed" ); 336 return false; 337 } 338 338 339 // Select removal by key or index 339 340 if ( key != NULL ) { 340 341 // Remove by key name 342 entry = ( psMetadataItem* ) psHashLookup( mdTable, key ); 343 if ( entry == NULL ) { 344 psError( __func__, "Couldn't find metadata item remove. Name: %s", key ); 345 return false; 346 } 347 348 numChildren = entry->items->size; 349 if ( entry->type == PS_META_ITEM_SET && numChildren > 0 ) { 350 351 // Table entry has children. Entry and children must be removed from metadata collection's list 352 psListSetIterator( mdList, PS_LIST_HEAD ); 353 entryChild = psListGetCurrent( mdList ); 354 while ( entryChild != NULL ) { 355 if ( !psListRemove( entry->items, entryChild, PS_LIST_UNKNOWN ) ) { 356 psError( __func__, "Couldn't remove metadata item from list. Name: %s", key ); 357 return false; 358 } 359 entryChild = psListGetNext( entry->items ); 360 } 361 } 362 363 // Remove entry from metadata collection's list 364 if ( !psListRemove( mdList, entry, PS_LIST_UNKNOWN ) ) { 341 342 // Remove by key name 343 entry = ( psMetadataItem* ) psHashLookup( mdTable, key ); 344 if ( entry == NULL ) { 345 psError( __func__, "Couldn't find metadata item remove. Name: %s", key ); 346 return false; 347 } 348 349 numChildren = entry->items->size; 350 if ( entry->type == PS_META_ITEM_SET && numChildren > 0 ) { 351 352 // Table entry has children. Entry and children must be removed from metadata collection's list 353 psListSetIterator( mdList, PS_LIST_HEAD ); 354 entryChild = psListGetCurrent( mdList ); 355 while ( entryChild != NULL ) { 356 if ( !psListRemove( entry->items, entryChild, PS_LIST_UNKNOWN ) ) { 365 357 psError( __func__, "Couldn't remove metadata item from list. Name: %s", key ); 366 358 return false; 367 359 } 368 369 // Remove entry from metadata collection's table 370 if ( !psHashRemove( mdTable, key ) ) { 371 psError( __func__, "Couldn't remove metadata item from table. Name: %s", key ); 372 return false; 373 } 374 } else { 375 376 // Remove by index 377 entry = psListGet( mdList, where ); 378 if ( entry == NULL ) { 379 psError( __func__, "Couldn't find metadata item from list. Index: %d", where ); 380 return false; 381 } 382 383 key = entry->name; 384 if ( key == NULL ) { 385 psError( __func__, "Null key name not allowed. Index: %d", where ); 386 return false; 387 } 388 389 // Use recursive remove, now that key is known 390 psMetadataRemove( md, PS_LIST_UNKNOWN, key ); 391 } 392 360 entryChild = psListGetNext( entry->items ); 361 } 362 } 363 364 // Remove entry from metadata collection's list 365 if ( !psListRemove( mdList, entry, PS_LIST_UNKNOWN ) ) { 366 psError( __func__, "Couldn't remove metadata item from list. Name: %s", key ); 367 return false; 368 } 369 370 // Remove entry from metadata collection's table 371 if ( !psHashRemove( mdTable, key ) ) { 372 psError( __func__, "Couldn't remove metadata item from table. Name: %s", key ); 373 return false; 374 } 375 } else { 376 377 // Remove by index 378 entry = psListGet( mdList, where ); 379 if ( entry == NULL ) { 380 psError( __func__, "Couldn't find metadata item from list. Index: %d", where ); 381 return false; 382 } 383 384 key = entry->name; 385 if ( key == NULL ) { 386 psError( __func__, "Null key name not allowed. Index: %d", where ); 387 return false; 388 } 389 390 // Use recursive remove, now that key is known 391 psMetadataRemove( md, PS_LIST_UNKNOWN, key ); 392 } 393 393 394 return true; 394 395 } … … 398 399 psHash * mdTable = NULL; 399 400 psMetadataItem *entry = NULL; 400 401 401 402 mdTable = md->table; 402 403 if ( mdTable == NULL ) { 403 psError( __func__, "Null metadata table not allowed" );404 return NULL;405 }406 404 psError( __func__, "Null metadata table not allowed" ); 405 return NULL; 406 } 407 407 408 if ( key == NULL ) { 408 psError( __func__, "Null key name not allowed" );409 return NULL;410 }411 409 psError( __func__, "Null key name not allowed" ); 410 return NULL; 411 } 412 412 413 entry = ( psMetadataItem* ) psHashLookup( mdTable, key ); 413 414 if ( entry == NULL ) { 414 psError( __func__, "Could not find metadata item with given key. Key: %s", key );415 return NULL;416 }417 415 psError( __func__, "Could not find metadata item with given key. Key: %s", key ); 416 return NULL; 417 } 418 418 419 return entry; 419 420 } … … 423 424 psList * mdList = NULL; 424 425 psMetadataItem *entry = NULL; 425 426 mdList = md->list; 427 if ( mdList == NULL ) { 428 psError( __func__, "Null metadata list not allowed" );429 return NULL;430 }431 426 427 mdList = md->list; 428 if ( mdList == NULL ) { 429 psError( __func__, "Null metadata list not allowed" ); 430 return NULL; 431 } 432 432 433 entry = ( psMetadataItem* ) psListGet( mdList, where ); 433 434 if ( entry == NULL ) { 434 psError( __func__, "Couldn't find metadata item with given index. Index: %d", where );435 return NULL;436 }437 435 psError( __func__, "Couldn't find metadata item with given index. Index: %d", where ); 436 return NULL; 437 } 438 438 439 return entry; 439 440 } … … 442 443 { 443 444 psList * mdList = NULL; 444 445 mdList = md->list; 446 if ( mdList == NULL ) { 447 psError( __func__, "Null metadata list not allowed" );448 return false;449 }450 445 446 mdList = md->list; 447 if ( mdList == NULL ) { 448 psError( __func__, "Null metadata list not allowed" ); 449 return false; 450 } 451 451 452 psListSetIterator( mdList, where ); 452 453 453 454 return true; 454 455 } … … 458 459 psList * mdList = NULL; 459 460 psMetadataItem *entry = NULL; 460 461 mdList = md->list; 462 if ( mdList == NULL ) { 463 psError( __func__, "Null metadata list not allowed" );464 return NULL;465 }466 467 mdList = md->list; 468 if ( mdList == NULL ) { 469 psError( __func__, "Null metadata list not allowed" );470 return NULL;471 }472 461 462 mdList = md->list; 463 if ( mdList == NULL ) { 464 psError( __func__, "Null metadata list not allowed" ); 465 return NULL; 466 } 467 468 mdList = md->list; 469 if ( mdList == NULL ) { 470 psError( __func__, "Null metadata list not allowed" ); 471 return NULL; 472 } 473 473 474 psListSetIterator( mdList, which ); 474 475 entry = psListGetCurrent( mdList ); 475 476 while ( entry != NULL ) { 476 if ( !strncmp( match, entry->name, strlen( match ) ) ) {477 478 // Match found479 return entry;480 }481 entry = psListGetNext( mdList );482 }483 477 if ( !strncmp( match, entry->name, strlen( match ) ) ) { 478 479 // Match found 480 return entry; 481 } 482 entry = psListGetNext( mdList ); 483 } 484 484 485 // Match not found 485 486 if ( entry == NULL ) { 486 psError( __func__, "Couldn't find metadata item with given match. Match: %s", match );487 }488 487 psError( __func__, "Couldn't find metadata item with given match. Match: %s", match ); 488 } 489 489 490 return entry; 490 491 } … … 494 495 psList * mdList = NULL; 495 496 psMetadataItem *entry = NULL; 496 497 mdList = md->list; 498 if ( mdList == NULL ) { 499 psError( __func__, "Null metadata list not allowed" );500 return NULL;501 }502 503 mdList = md->list; 504 if ( mdList == NULL ) { 505 psError( __func__, "Null metadata list not allowed" );506 return NULL;507 }508 497 498 mdList = md->list; 499 if ( mdList == NULL ) { 500 psError( __func__, "Null metadata list not allowed" ); 501 return NULL; 502 } 503 504 mdList = md->list; 505 if ( mdList == NULL ) { 506 psError( __func__, "Null metadata list not allowed" ); 507 return NULL; 508 } 509 509 510 psListSetIterator( mdList, which ); 510 511 entry = psListGetCurrent( mdList ); 511 512 while ( entry != NULL ) { 512 if ( !strncmp( match, entry->name, strlen( match ) ) ) {513 514 // Match found515 return entry;516 }517 entry = psListGetPrevious( mdList );518 }519 513 if ( !strncmp( match, entry->name, strlen( match ) ) ) { 514 515 // Match found 516 return entry; 517 } 518 entry = psListGetPrevious( mdList ); 519 } 520 520 521 // Match not found 521 522 if ( entry == NULL ) { 522 psError( __func__, "Couldn't find metadata item with given match. Match: %s", match );523 }524 523 psError( __func__, "Couldn't find metadata item with given match. Match: %s", match ); 524 } 525 525 526 return entry; 526 527 } … … 529 530 { 530 531 psMetadataType type; 531 532 532 533 if ( fd == NULL ) { 533 psError( __func__, "Null file descriptor not allowed" );534 return ;535 }536 534 psError( __func__, "Null file descriptor not allowed" ); 535 return ; 536 } 537 537 538 if ( format == NULL ) { 538 psError( __func__, "Null format not allowed" );539 return ;540 }541 539 psError( __func__, "Null format not allowed" ); 540 return ; 541 } 542 542 543 if ( metadataItem == NULL ) { 543 psError( __func__, "Null metadata not allowed" );544 return ;545 }546 544 psError( __func__, "Null metadata not allowed" ); 545 return ; 546 } 547 547 548 type = metadataItem->type; 548 549 549 550 switch ( type ) { 550 case PS_META_BOOL:551 fprintf( fd, format, metadataItem->data.B );552 break;553 case PS_META_S32:554 fprintf( fd, format, metadataItem->data.S32 );555 break;556 case PS_META_F32:557 fprintf( fd, format, metadataItem->data.F32 );558 break;559 case PS_META_F64:560 fprintf( fd, format, metadataItem->data.F64 );561 break;562 case PS_META_STR:563 fprintf( fd, format, metadataItem->data.V );564 break;565 case PS_META_ITEM_SET:566 case PS_META_IMG:567 case PS_META_JPEG:568 case PS_META_PNG:569 case PS_META_ASTROM:570 case PS_META_UNKNOWN:571 default:572 psError( __func__, " Invalid psMetadataType to print: %d", type );573 }551 case PS_META_BOOL: 552 fprintf( fd, format, metadataItem->data.B ); 553 break; 554 case PS_META_S32: 555 fprintf( fd, format, metadataItem->data.S32 ); 556 break; 557 case PS_META_F32: 558 fprintf( fd, format, metadataItem->data.F32 ); 559 break; 560 case PS_META_F64: 561 fprintf( fd, format, metadataItem->data.F64 ); 562 break; 563 case PS_META_STR: 564 fprintf( fd, format, metadataItem->data.V ); 565 break; 566 case PS_META_ITEM_SET: 567 case PS_META_IMG: 568 case PS_META_JPEG: 569 case PS_META_PNG: 570 case PS_META_ASTROM: 571 case PS_META_UNKNOWN: 572 default: 573 psError( __func__, " Invalid psMetadataType to print: %d", type ); 574 } 574 575 } 575 576 … … 590 591 int keyNum = 0; 591 592 psMetadataType metadataItemType; 592 593 593 594 if ( fd == NULL ) { 594 psError( __func__, "Null FITS file descriptor not allowed" );595 return NULL;596 }597 595 psError( __func__, "Null FITS file descriptor not allowed" ); 596 return NULL; 597 } 598 598 599 if ( extname == NULL && extnum == 0 ) { 599 psError( __func__, "Null extname AND extnum = 0 not allowed" ); 600 return NULL; 601 } else if ( extname && extnum ) { 600 psError( __func__, "Null extname AND extnum = 0 not allowed" ); 601 return NULL; 602 } else 603 if ( extname && extnum ) { 602 604 psError( __func__, "Both extname AND extnum arguments should not have values." ); 603 605 return NULL; 604 606 } 605 607 606 608 // Allocate metadata if user didn't 607 609 if ( output == NULL ) { 608 output = psMetadataAlloc();609 }610 610 output = psMetadataAlloc(); 611 } 612 611 613 // Move to user designated HDU number or HDU name in FITS file. HDU numbers starts at one. 612 614 if ( extname == NULL ) { 613 if ( fits_movabs_hdu( fd, extnum, &hduType, &status ) != 0 ) { 614 fits_get_errstatus( status, fitsErr ); 615 psError( __func__, "FITS error while locating header: %s", fitsErr ); 616 status = 0; 617 return output; 618 } 619 } else if ( extnum > 0 ) { 615 if ( fits_movabs_hdu( fd, extnum, &hduType, &status ) != 0 ) { 616 fits_get_errstatus( status, fitsErr ); 617 psError( __func__, "FITS error while locating header: %s", fitsErr ); 618 status = 0; 619 return output; 620 } 621 } else 622 if ( extnum > 0 ) { 620 623 tempExtname = ( char* ) extname; 621 624 if ( fits_movnam_hdu( fd, ANY_HDU, tempExtname, 0, &status ) != 0 ) { 622 fits_get_errstatus( status, fitsErr );623 psError( __func__, "FITS error while locating header: %s", fitsErr );624 status = 0;625 return output;626 }627 } 628 625 fits_get_errstatus( status, fitsErr ); 626 psError( __func__, "FITS error while locating header: %s", fitsErr ); 627 status = 0; 628 return output; 629 } 630 } 631 629 632 // Get number of key names 630 633 if ( fits_get_hdrpos( fd, &numKeys, &keyNum, &status ) != 0 ) { 634 fits_get_errstatus( status, fitsErr ); 635 psError( __func__, "FITS error while reading keys: %s", fitsErr ); 636 status = 0; 637 return output; 638 } 639 640 // Get each key name. Keywords start at one. 641 for ( i = 1; i <= numKeys; i++ ) { 642 if ( fits_read_keyn( fd, i, keyName, keyValue, keyComment, &status ) != 0 ) { 631 643 fits_get_errstatus( status, fitsErr ); 632 psError( __func__, "FITS error while reading key s: %s", fitsErr );644 psError( __func__, "FITS error while reading key number %d: %s", i, fitsErr ); 633 645 status = 0; 634 646 return output; 635 647 } 636 637 // Get each key name. Keywords start at one. 638 for ( i = 1; i <= numKeys; i++ ) { 639 if ( fits_read_keyn( fd, i, keyName, keyValue, keyComment, &status ) != 0 ) { 640 fits_get_errstatus( status, fitsErr ); 641 psError( __func__, "FITS error while reading key number %d: %s", i, fitsErr ); 642 status = 0; 643 return output; 644 } 645 if ( fits_get_keytype( keyValue, &keyType, &status ) != 0 ) { 646 fits_get_errstatus( status, fitsErr ); 647 if ( status != VALUE_UNDEFINED ) { 648 psError( __func__, "FITS error while determining key type: %s", fitsErr ); 649 status = 0; 650 return output; 651 } else { 652 // Some keywords are still valid even though they don't have a type or value, like COMMENTS 653 keyType = 'C'; 654 status = 0; 655 } 656 } 657 658 switch ( keyType ) { 659 case 'I': 660 metadataItemType = PS_META_S32; 661 success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, atoi( keyValue ) ); 662 break; 663 case 'F': 664 metadataItemType = PS_META_F64; 665 success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, atof( keyValue ) ); 666 break; 667 case 'C': 668 metadataItemType = PS_META_STR; 669 success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, keyValue ); 670 break; 671 case 'L': 672 metadataItemType = PS_META_BOOL; 673 tempBool = ( keyValue[ 0 ] == 'T' ) ? 1 : 0; 674 success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, tempBool ); 675 break; 676 case 'U': 677 case 'X': 678 default: 679 psError( __func__, "Invalid psMetadataType: %c", keyType ); 680 return output; 681 } 682 683 if ( !success ) { 684 psError( __func__, "Failed to add metadata item. Name: %s", keyName ); 685 } 686 } 687 648 if ( fits_get_keytype( keyValue, &keyType, &status ) != 0 ) { 649 fits_get_errstatus( status, fitsErr ); 650 if ( status != VALUE_UNDEFINED ) { 651 psError( __func__, "FITS error while determining key type: %s", fitsErr ); 652 status = 0; 653 return output; 654 } else { 655 // Some keywords are still valid even though they don't have a type or value, like COMMENTS 656 keyType = 'C'; 657 status = 0; 658 } 659 } 660 661 switch ( keyType ) { 662 case 'I': 663 metadataItemType = PS_META_S32; 664 success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, atoi( keyValue ) ); 665 break; 666 case 'F': 667 metadataItemType = PS_META_F64; 668 success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, atof( keyValue ) ); 669 break; 670 case 'C': 671 metadataItemType = PS_META_STR; 672 success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, keyValue ); 673 break; 674 case 'L': 675 metadataItemType = PS_META_BOOL; 676 tempBool = ( keyValue[ 0 ] == 'T' ) ? 1 : 0; 677 success = psMetadataAdd( output, PS_LIST_HEAD, keyName, metadataItemType, keyComment, tempBool ); 678 break; 679 case 'U': 680 case 'X': 681 default: 682 psError( __func__, "Invalid psMetadataType: %c", keyType ); 683 return output; 684 } 685 686 if ( !success ) { 687 psError( __func__, "Failed to add metadata item. Name: %s", keyName ); 688 } 689 } 690 688 691 return output; 689 692 } -
trunk/psLib/src/types/psMetadata.h
r1382 r1385 10 10 * @author Ross Harman, MHPCC 11 11 * 12 * @version $Revision: 1.1 1$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-08-04 2 2:11:09 $12 * @version $Revision: 1.12 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2004-08-04 23:37:39 $ 14 14 * 15 15 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 59 59 */ 60 60 typedef struct psMetadataItem 61 { 62 const int id; ///< Unique ID for metadata item. 63 char *restrict name; ///< Name of metadata item. 64 psMetadataType type; ///< Type of metadata item. 65 union 61 66 { 62 const int id; ///< Unique ID for metadata item. 63 char *restrict name; ///< Name of metadata item. 64 psMetadataType type; ///< Type of metadata item. 65 union 66 { 67 bool B; 68 psS32 S32; ///< Signed 32-bit integer data. 69 psF32 F32; ///< Single-precision float data. 70 psF64 F64; ///< Double-precision float data. 71 psPTR V; ///< Pointer to other type of data. 72 }data; ///< Union for data types. 73 char *comment; ///< Optional comment ("", not NULL). 74 psList *restrict items; ///< List of psMetadataItems with same name. 75 } 67 bool B; 68 psS32 S32; ///< Signed 32-bit integer data. 69 psF32 F32; ///< Single-precision float data. 70 psF64 F64; ///< Double-precision float data. 71 psPTR V; ///< Pointer to other type of data. 72 }data; ///< Union for data types. 73 char *comment; ///< Optional comment ("", not NULL). 74 psList *restrict items; ///< List of psMetadataItems with same name. 75 } 76 76 psMetadataItem; 77 77 … … 83 83 */ 84 84 typedef struct psMetadata 85 {86 psList* restrict list;87 psHash* restrict table;88 }85 { 86 psList* restrict list; 87 psHash* restrict table; 88 } 89 89 psMetadata; 90 90
Note:
See TracChangeset
for help on using the changeset viewer.
