OPERA  1.0
Open source echelle spectrograph reduction pipeline
libraries/operaImage.h
Go to the documentation of this file.
00001 #ifndef LIBOPERAIMAGE_H
00002 #define LIBOPERAIMAGE_H
00003 /*******************************************************************
00004  ****                LIBRARY FOR OPERA v1.0                     ****
00005  *******************************************************************
00006  Library name: operaImage
00007  Version: 1.0
00008  Description: ThisC library implements low level image routines..
00009  Author(s): CFHT OPERA team
00010  Affiliation: Canada France Hawaii Telescope 
00011  Location: Hawaii USA
00012  Date: Aug/2011
00013  Contact: teeple@cfht.hawaii.edu
00014  
00015  Copyright (C) 2011  Opera Pipeline team, Canada France Hawaii Telescope
00016  
00017  This program is free software: you can redistribute it and/or modify
00018  it under the terms of the GNU General Public License as published by
00019  the Free Software Foundation, either version 3 of the License, or
00020  (at your option) any later version.
00021  
00022  This program is distributed in the hope that it will be useful,
00023  but WITHOUT ANY WARRANTY; without even the implied warranty of
00024  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00025  GNU General Public License for more details.
00026  
00027  You should have received a copy of the GNU General Public License
00028  along with this program.  If not, see:
00029  http://software.cfht.hawaii.edu/licenses
00030  -or-
00031  http://www.gnu.org/licenses/gpl-3.0.html
00032  ********************************************************************/
00033 
00034 // $Date$
00035 // $Id$
00036 // $Revision$
00037 // $Locker$
00038 // $Log$
00039 
00040 /*
00041  * Image routines.
00042  *
00043  */
00044 #include <stdio.h>
00045 #include <stdlib.h>
00046 #include <math.h>
00047 
00048 #include "operaError.h"
00049 
00050 #define MAXIMAGES 1000
00051 
00052 /*
00053  * The inline functions below operates img by a constant  (they overrride original img values)
00054  */
00055 inline void operaSumImbyConstant(long npixels, float *img, float number){while (npixels--) *img++ += number;}
00056 inline void operaSubtractImbyConstant(long npixels, float *img, float number){while (npixels--) *img++ -= number;}
00057 inline void operaMultiplyImbyConstant(long npixels, float *img, float number){while (npixels--) *img++ *= number;}
00058 inline void operaDivideImbyConstant(long npixels, float *img, float number){while (npixels--) *img++ /= number;}
00059 inline void operaImSubtractIm(long npixels, float *img1, float *img2) {while (npixels--) *img1++ -= *img2++;}
00060 float *medianCombineFloat(unsigned depth, long npixels, float *master, float *arrays[]);
00061 unsigned short *operaArrayMedianCombineUSHORT(unsigned depth, long npixels, unsigned short *master, unsigned short *arrays[]);
00062 void operaImMean(unsigned depth, long npixels, float *master, float *arrays[]); 
00063 void operaImWeightedMean(unsigned depth, long npixels, float *master, float *arrays[], float *weights[]);
00064 void operaImSig(unsigned depth, long npixels, float *sigarray, float *arrays[], float *master); 
00065 void operaImWeightedSig(unsigned depth, long npixels, float *sigarray, float *arrays[], float *weights[], float *master);
00066 void operaImAvgSigClip(unsigned depth, long npixels, float *master, float *arrays[], unsigned nsig);
00067 float operaCCDVarDiff(unsigned depth, long npixels, float *arrays[], float *weight);
00068 void operaImVarDiff(unsigned depth, long npixels, float *arrays[], float *diffvarimg);
00069 
00078 inline void operaImMeanQuick(unsigned depth, long npixels, float *master, float *arrays[]) 
00079 {
00080         long np;
00081         for (unsigned d=0; d<depth; d++) {
00082                 float *p = master;              
00083                 float *arr = arrays[d];
00084                 np = npixels;
00085                 
00086                 while (np--)
00087                         *p++ += *arr++;
00088         }       
00089         np = npixels;
00090         float *p = master;      
00091         while (np--)
00092                 *p++ /= (float)depth;   
00093 }       
00094 
00105 inline void operaImWeightedMeanQuick(unsigned depth, long npixels, float *master, float *arrays[], float *weights[]) 
00106 {
00107         float *weightsum = (float *)malloc(sizeof(float)*npixels);
00108         memset(weightsum, sizeof(float)*npixels, 0);
00109         
00110         for (unsigned d=0; d<depth; d++) {
00111                 long np = npixels;
00112                 
00113                 float *p = master;
00114                 float *arr = arrays[d];
00115                 float *pwi = weights[d];
00116                 float *ws = weightsum;          
00117                 
00118                 while (np--) {
00119                         (*p++) = (*arr++) * (*pwi);
00120                         (*ws++) += *pwi++;
00121                 }
00122         }
00123         
00124         long np = npixels;
00125         float *p = master;
00126         float *ws = weightsum;  
00127         while (np--) {
00128                 *p++ /= *ws++;
00129         }
00130         free(weightsum);
00131 }       
00132 
00143 inline void operaImSigQuick(unsigned depth, long npixels, float *sigarray, float *arrays[], float *master) 
00144 {
00145         long np;
00146         for (unsigned d=0; d<depth; d++) {
00147                 float *p = master;              
00148                 float *arr = arrays[d];
00149                 float *sig = sigarray;
00150                 np = npixels;
00151                 
00152                 while (np--){
00153                         *sig++ += (*arr - *p)*(*arr - *p);
00154                         arr++;
00155                         p++;
00156                 }       
00157         }       
00158         np = npixels;
00159         float *sig = sigarray;  
00160         while (np--) {
00161                 *sig = sqrt(*sig/(float)depth); 
00162                 sig++;
00163         }       
00164 }       
00165 
00176 inline void operaImWeightedSigQuick(unsigned depth, long npixels, float *sigarray, float *arrays[], float *weights[], float *master) 
00177 {
00178         float *weightsum = (float *)malloc(sizeof(float)*npixels);
00179         memset(weightsum, sizeof(float)*npixels, 0);
00180         
00181         long np;
00182         for (unsigned d=0; d<depth; d++) {
00183                 float *p = master;              
00184                 float *arr = arrays[d];
00185                 float *sig = sigarray;
00186                 float *pwi = weights[d];
00187                 float *ws = weightsum;  
00188                 
00189                 np = npixels;
00190                 
00191                 while (np--){
00192                         *sig++ += (*pwi)*(*arr - *p)*(*arr - *p);
00193                         *ws++ += *pwi++;                        
00194                         arr++;
00195                         p++;
00196                 }       
00197         }       
00198         
00199         np = npixels;
00200         float *sig = sigarray;  
00201         float *ws = weightsum;  
00202         
00203         while (np--) {
00204                 *sig = sqrt( *sig / (*ws++) );  
00205                 sig++;
00206         }       
00207         free(weightsum);        
00208 }       
00209 
00220 inline void operaImAvgSigClipQuick(unsigned depth, long npixels, float *master, float *arrays[], unsigned nsig) 
00221 {
00222         long np;
00223         unsigned d;
00224         
00225         float *avg = (float *)malloc(sizeof(float)*npixels);
00226         memset(avg, sizeof(float)*npixels, 0);  
00227         
00228         float *sigarray = (float *)malloc(sizeof(float)*npixels);
00229         memset(sigarray, sizeof(float)*npixels, 0);     
00230         
00231         for (d=0; d<depth; d++) {
00232                 float *p = avg;         
00233                 float *arr = arrays[d];
00234                 np = npixels;
00235                 
00236                 while (np--)
00237                         *p++ += *arr++;
00238         }       
00239         
00240         np = npixels;
00241         float *p = avg; 
00242         while (np--) {
00243                 *p++ /= (float)depth;   
00244         }       
00245         
00246         for (d=0; d<depth; d++) {
00247                 float *p = avg;         
00248                 float *arr = arrays[d];
00249                 float *sig = sigarray;
00250                 np = npixels;
00251                 
00252                 while (np--){
00253                         *sig++ += (*arr - *p)*(*arr - *p);
00254                         arr++;
00255                         p++;
00256                 }       
00257         }       
00258         np = npixels;
00259         float *sig = sigarray;  
00260         while (np--) {
00261                 *sig = sqrt(*sig/(float)depth); 
00262                 sig++;
00263         }               
00264         
00265         float *weightsum = (float *)malloc(sizeof(float)*npixels);
00266         memset(weightsum, sizeof(float)*npixels, 0);    
00267         
00268         for (d=0; d<depth; d++) {
00269                 float *arr = arrays[d];
00270                 float *sig = sigarray;
00271                 float *p = avg;
00272                 float *upp = master;    
00273                 float *w = weightsum;           
00274                 np = npixels;           
00275                 
00276                 while (np--) {  
00277                         if(*arr > (*p - *sig*(float)nsig) && *arr < (*p + *sig*(float)nsig)) {
00278                                 *upp += *arr;
00279                                 *w += 1;
00280                         }
00281                         arr++;
00282                         p++;
00283                         sig++;
00284                         upp++;
00285                         w++;
00286                 }               
00287         }
00288         
00289         np = npixels;
00290         float *upp = master;    
00291         float *w = weightsum;           
00292         float *pold = avg;
00293         
00294         while (np--) {
00295                 if(*upp == 0) {
00296                         *upp++ = *pold; // if all points are clipped then take regular mean
00297                 }       else {
00298                         *upp++ /= *w;   
00299                 }
00300                 pold++;
00301                 w++;
00302         }               
00303         
00304         free(weightsum);
00305         free(avg);
00306         free(sigarray);
00307 }
00308 #endif
00309