Ignore:
Timestamp:
Sep 6, 2019 2:29:24 PM (4 years ago)
Author:
krzywon
Message:

Add elliptical averaging as an option to the average parameters window. The method called currently performs an annular average.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sans/Dev/branches/elliptical_averaging/NCNR_User_Procedures/Reduction/SANS/RectAnnulAvg.ipf

    r961 r1207  
    660660        Return 0 
    661661End 
     662 
     663//performs an elliptical average using isointensity contours, centered on a  
     664//specified q-value (Intensity vs. angle) 
     665//the parameters in the global keyword-string must have already been set somewhere 
     666//either directly or from the protocol 
     667// 
     668//the input (data in the "type" folder) must be on linear scale - the calling routine is 
     669//responsible for this 
     670//averaged data is written to the data folder and plotted. data is not written 
     671//to disk from this routine. 
     672// 
     673Function EllipticalAverageTo1D(type) 
     674        String type 
     675         
     676        SVAR keyListStr = root:myGlobals:Protocols:gAvgInfoStr 
     677         
     678        //type is the data type to do the averaging on, and will be set as the current folder 
     679        //get the current displayed data (so the correct folder is used) 
     680        String destPath = "root:Packages:NIST:"+type 
     681         
     682        Variable xcenter,ycenter,x0,y0,sx,sx3,sy,sy3,dtsize,dtdist 
     683        Variable rcentr,large_num,small_num,dtdis2,nq,xoffst,xbm,ybm,ii 
     684        Variable rc,delr,rlo,rhi,dphi,nphi,dr 
     685        Variable lambda,trans 
     686        Wave reals = $(destPath + ":RealsRead") 
     687 
     688        // center of detector, for non-linear corrections 
     689        NVAR pixelsX = root:myGlobals:gNPixelsX 
     690        NVAR pixelsY = root:myGlobals:gNPixelsY 
     691         
     692        xcenter = pixelsX/2 + 0.5               // == 64.5 for 128x128 Ordela 
     693        ycenter = pixelsY/2 + 0.5               // == 64.5 for 128x128 Ordela 
     694         
     695        // beam center, in pixels 
     696        x0 = reals[16] 
     697        y0 = reals[17] 
     698        //detector calibration constants 
     699        sx = reals[10]          //mm/pixel (x) 
     700        sx3 = reals[11]         //nonlinear coeff 
     701        sy = reals[13]          //mm/pixel (y) 
     702        sy3 = reals[14]         //nonlinear coeff 
     703         
     704        dtsize = 10*reals[20]           //det size in mm 
     705        dtdist = 1000*reals[18] // det distance in mm 
     706        lambda = reals[26] 
     707         
     708        Variable qc = NumberByKey("QCENTER",keyListStr,"=",";") 
     709        Variable nw = NumberByKey("QDELTA",keyListStr,"=",";") 
     710         
     711        dr = 1                  //minimum annulus width, keep this fixed at one 
     712        NVAR numPhiSteps = root:Packages:NIST:gNPhiSteps 
     713        nphi = numPhiSteps              //number of anular sectors is set by users 
     714         
     715        rc = 2*dtdist*asin(qc*lambda/4/Pi)              //in mm 
     716        delr = nw*sx/2 
     717        rlo = rc-delr 
     718        rhi = rc + delr 
     719        dphi = 360/nphi 
     720 
     721        /// data wave is data in the current folder which was set at the top of the function 
     722        Wave data=$(destPath + ":data") 
     723        //Check for the existence of the mask, if not, make one (local to this folder) that is null 
     724         
     725        if(WaveExists($"root:Packages:NIST:MSK:data") == 0) 
     726                Print "There is no mask file loaded (WaveExists)- the data is not masked" 
     727                Make/O/N=(pixelsX,pixelsY) $(destPath + ":mask") 
     728                WAVE mask = $(destPath + ":mask") 
     729                mask = 0 
     730        else 
     731                Wave mask=$"root:Packages:NIST:MSK:data" 
     732        Endif 
     733         
     734        rcentr = 150            //pixels within rcentr of beam center are broken into 9 parts 
     735        // values for error if unable to estimate value 
     736        //large_num = 1e10 
     737        large_num = 1           //1e10 value (typically sig of last data point) plots poorly, arb set to 1 
     738        small_num = 1e-10 
     739         
     740        // output wave are expected to exist (?) initialized to zero, what length? 
     741        // 300 points on VAX --- 
     742        Variable wavePts=500 
     743        Make/O/N=(wavePts) $(destPath + ":phival"),$(destPath + ":aveint") 
     744        Make/O/N=(wavePts) $(destPath + ":ncells"),$(destPath + ":sig"),$(destPath + ":sigave") 
     745        WAVE phival = $(destPath + ":phival") 
     746        WAVE aveint = $(destPath + ":aveint") 
     747        WAVE ncells = $(destPath + ":ncells") 
     748        WAVE sig = $(destPath + ":sig") 
     749        WAVE sigave = $(destPath + ":sigave") 
     750 
     751        phival = 0 
     752        aveint = 0 
     753        ncells = 0 
     754        sig = 0 
     755        sigave = 0 
     756 
     757        dtdis2 = dtdist^2 
     758        nq = 1 
     759        xoffst=0 
     760        //distance of beam center from detector center 
     761        xbm = FX(x0,sx3,xcenter,sx) 
     762        ybm = FY(y0,sy3,ycenter,sy) 
     763                 
     764        //BEGIN AVERAGE ********** 
     765        Variable xi,xd,x,y,yd,yj,nd,fd,nd2,iphi,ntotal,var 
     766        Variable jj,data_pixel,xx,yy,ll,kk,rij,phiij,avesq,aveisq 
     767 
     768        // IGOR arrays are indexed from [0][0], FORTAN from (1,1) (and the detector too) 
     769        // loop index corresponds to FORTRAN (old code)  
     770        // and the IGOR array indices must be adjusted (-1) to the correct address 
     771        ntotal = 0 
     772        ii=1 
     773        do 
     774                xi = ii 
     775                xd = FX(xi,sx3,xcenter,sx) 
     776                x = xoffst + xd -xbm            //x and y are in mm 
     777                 
     778                jj = 1 
     779                do 
     780                        data_pixel = data[ii-1][jj-1]           //assign to local variable 
     781                        yj = jj 
     782                        yd = FY(yj,sy3,ycenter,sy) 
     783                        y = yd - ybm 
     784                        if(!(mask[ii-1][jj-1]))                 //masked pixels = 1, skip if masked (this way works...) 
     785                                nd = 1 
     786                                fd = 1 
     787                                if( (abs(x) > rcentr) || (abs(y) > rcentr))     //break pixel into 9 equal parts 
     788                                        nd = 3 
     789                                        fd = 2 
     790                                Endif 
     791                                nd2 = nd^2 
     792                                ll = 1          //"el-el" loop index 
     793                                do 
     794                                        xx = x + (ll - fd)*sx/3 
     795                                        kk = 1 
     796                                        do 
     797                                                yy = y + (kk - fd)*sy/3 
     798                                                //test to see if center of pixel (i,j) lies in annulus 
     799                                                rij = sqrt(x*x + y*y)/dr + 1.001 
     800                                                //check whether pixel lies within width band 
     801                                                if((rij > rlo) && (rij < rhi)) 
     802                                                        //in the annulus, do something 
     803                                                        if (yy >= 0) 
     804                                                                //phiij is in degrees 
     805                                                                phiij = atan2(yy,xx)*180/Pi             //0 to 180 deg 
     806                                                        else 
     807                                                                phiij = 360 + atan2(yy,xx)*180/Pi               //180 to 360 deg 
     808                                                        Endif 
     809                                                        if (phiij > (360-0.5*dphi)) 
     810                                                                phiij -= 360 
     811                                                        Endif 
     812                                                        iphi = trunc(phiij/dphi + 1.501) 
     813                                                        aveint[iphi-1] += 9*data_pixel/nd2 
     814                                                        sig[iphi-1] += 9*data_pixel*data_pixel/nd2 
     815                                                        ncells[iphi-1] += 9/nd2 
     816                                                        ntotal += 9/nd2 
     817                                                Endif           //check if in annulus 
     818                                                kk+=1 
     819                                        while(kk<=nd) 
     820                                        ll += 1 
     821                                while(ll<=nd) 
     822                        Endif           //masked pixel check 
     823                        jj += 1 
     824                while (jj<=pixelsY) 
     825                ii += 1 
     826        while(ii<=pixelsX)              //end of the averaging 
     827                 
     828        //compute phi-values and errors 
     829         
     830        ntotal /=9 
     831         
     832        kk = 1 
     833        do 
     834                phival[kk-1] = dphi*(kk-1) 
     835                if(ncells[kk-1] != 0) 
     836                        aveint[kk-1] = aveint[kk-1]/ncells[kk-1] 
     837                        avesq = aveint[kk-1]*aveint[kk-1] 
     838                        aveisq = sig[kk-1]/ncells[kk-1] 
     839                        var = aveisq - avesq 
     840                        if (var <=0 ) 
     841                                sig[kk-1] = 0 
     842                                sigave[kk-1] = 0 
     843                                ncells[kk-1] /=9 
     844                        else 
     845                                if(ncells[kk-1] > 9) 
     846                                        sigave[kk-1] = sqrt(9*var/(ncells[kk-1]-9)) 
     847                                        sig[kk-1] = sqrt( abs(aveint[kk-1])/(ncells[kk-1]/9) ) 
     848                                        ncells[kk-1] /=9 
     849                                else 
     850                                        sig[kk-1] = 0 
     851                                        sigave[kk-1] = 0 
     852                                        ncells[kk-1] /=9 
     853                                Endif 
     854                        Endif 
     855                Endif 
     856                kk+=1 
     857        while(kk<=nphi) 
     858         
     859        // data waves were defined as 200 points (=wavePts), but now have less than that (nphi) points 
     860        // use DeletePoints to remove junk from end of waves 
     861        Variable startElement,numElements 
     862        startElement = nphi 
     863        numElements = wavePts - startElement 
     864        DeletePoints startElement,numElements, phival,aveint,ncells,sig,sigave 
     865         
     866        //////////////end of VAX Phibin.for 
     867                 
     868        //angle dependent transmission correction is not done in phiave 
     869        Ann_1D_Graph(aveint,phival,sigave) 
     870         
     871        //get rid of the default mask, if one was created (it is in the current folder) 
     872        //don't just kill "mask" since it might be pointing to the one in the MSK folder 
     873        Killwaves/z $(destPath+":mask") 
     874                 
     875        //return to root folder (redundant) 
     876        SetDataFolder root: 
     877         
     878        Return 0 
     879End 
Note: See TracChangeset for help on using the changeset viewer.