source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS/ProDiv.ipf @ 430

Last change on this file since 430 was 418, checked in by ajj, 14 years ago

Moving data folders into root:Packages:NIST

This could be hairy.

File size: 7.9 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=5.0
3#pragma IgorVersion=6.0
4
5
6//********************
7// Vers. 1.2 092101
8//
9// Procedures to create a "DIV" file for use as a detector sensitivity file
10// Follows the same procedure as PRODIV on the VAX
11// -requires two "full" reduced runs from plexiglass or water
12// -prompts the user for the locations of the offset and no-offset files
13// and for the range of data to replace
14// - then writes of the "div" file and fake-VAX format, which is rather ugly
15// since the DIV file is floating point...
16//
17//
18// 08 AUG 03
19// allowed for creation of DIV files on 8m SANS with two beamstops
20//
21// JAN2006 - not modified! still hard-wired to take a 128x128 detector image
22//
23//*********************
24
25//writes an VAX-style WORK file, "exactly" as it would be output from the VAX
26//except for the "dummy" header and the record markers - the record marker bytes are
27// in the files - they are just written as zeros and are meaningless
28//file is:
29//      516 bytes header
30// 128x128=16384 (x4) bytes of data
31// + 2 byte record markers interspersed just for fun
32// = 66116 bytes
33//prompts for name of the output file.
34//
35Function WriteVAXWorkFile(type)
36        String type
37       
38        Wave data=$("root:Packages:NIST:"+type+":data")
39       
40        Variable refnum,ii=0,hdrBytes=516,a,b,offset
41        String fullpath=""
42       
43        Duplicate/O data,tempData
44        Redimension/S/N=(128*128) tempData
45        tempData *= 4
46       
47        PathInfo/S catPathName
48        fullPath = DoSaveFileDialog("Save data as")       //won't actually open the file
49        If(cmpstr(fullPath,"")==0)
50                //user cancel, don't write out a file
51          Close/A
52          Abort "no data file was written"
53        Endif
54       
55        Make/B/O/N=(hdrBytes) hdrWave
56        hdrWave=0
57        FakeDIVHeader(hdrWave)
58       
59        Make/Y=2/O/N=(510) bw510                //Y=2 specifies 32 bit (=4 byte) floating point
60        Make/Y=2/O/N=(511) bw511
61        Make/Y=2/O/N=(48) bw48
62
63        Make/O/B/N=2 recWave            //two bytes
64
65        //actually open the file
66        Open/C="????"/T="TEXT" refNum as fullpath
67        FSetPos refNum, 0
68        //write header bytes (to be skipped when reading the file later)
69       
70        FBinWrite /F=1 refnum,hdrWave
71       
72        ii=0
73        a=0
74        do
75                //write 511 4-byte values (little-endian order), 4* true value
76                bw511[] = tempData[p+a]
77                FBinWrite /B=3/F=4 refnum,bw511
78                a+=511
79                //write a 2-byte record marker
80                FBinWrite refnum,recWave
81               
82                //write 510 4-byte values (little-endian) 4* true value
83                bw510[] = tempData[p+a]
84                FBinWrite /B=3/F=4 refnum,bw510
85                a+=510
86               
87                //write a 2-byte record marker
88                FBinWrite refnum,recWave
89               
90                ii+=1   
91        while(ii<16)
92        //write out last 48  4-byte values (little-endian) 4* true value
93        bw48[] = tempData[p+a]
94        FBinWrite /B=3/F=4 refnum,bw48
95        //close the file
96        Close refnum
97       
98        //go back through and make it look like a VAX datafile
99        Make/W/U/O/N=(511*2) int511             // /W=16 bit signed integers /U=unsigned
100        Make/W/U/O/N=(510*2) int510
101        Make/W/U/O/N=(48*2) int48
102       
103        //skip the header for now
104        Open/A/T="????TEXT" refnum as fullPath
105        FSetPos refnum,0
106       
107        offset=hdrBytes
108        ii=0
109        do
110                //511*2 integers
111                FSetPos refnum,offset
112                FBinRead/B=2/F=2 refnum,int511
113                Swap16BWave(int511)
114                FSetPos refnum,offset
115                FBinWrite/B=2/F=2 refnum,int511
116               
117                //skip 511 4-byte FP = (511*2)*2 2byte int  + 2 bytes record marker
118                offset += 511*2*2 + 2
119               
120                //510*2 integers
121                FSetPos refnum,offset
122                FBinRead/B=2/F=2 refnum,int510
123                Swap16BWave(int510)
124                FSetPos refnum,offset
125                FBinWrite/B=2/F=2 refnum,int510
126               
127                //
128                offset += 510*2*2 + 2
129               
130                ii+=1
131        while(ii<16)
132        //48*2 integers
133        FSetPos refnum,offset
134        FBinRead/B=2/F=2 refnum,int48
135        Swap16BWave(int48)
136        FSetPos refnum,offset
137        FBinWrite/B=2/F=2 refnum,int48
138
139        //move to EOF and close
140        FStatus refnum
141        FSetPos refnum,V_logEOF
142       
143        Close refnum
144       
145        Killwaves/Z hdrWave,bw48,bw511,bw510,recWave,temp16,int511,int510,int48
146End
147
148// given a 16 bit integer wave, read in as 2-byte pairs of 32-bit FP data
149// swap the order of the 2-byte pairs
150//
151Function Swap16BWave(w)
152        Wave w
153
154        Duplicate/O w,temp16
155        //Variable num=numpnts(w),ii=0
156
157        //elegant way to swap even/odd values, using wave assignments
158        w[0,*;2] = temp16[p+1]
159        w[1,*;2] = temp16[p-1]
160
161//crude way, using a loop       
162//      for(ii=0;ii<num;ii+=2)
163//              w[ii] = temp16[ii+1]
164//              w[ii+1] = temp16[ii]
165//      endfor
166       
167        return(0)       
168End
169
170// writes a fake label into the header of the DIV file
171//
172Function FakeDIVHeader(hdrWave)
173        WAVE hdrWave
174       
175        //put some fake text into the sample label position (60 characters=60 bytes)
176        String day=date(),tim=time(),lbl=""
177        Variable start=98,num,ii
178       
179        lbl = "Sensitivity (DIV) created "+day +" "+tim
180        num=strlen(lbl)
181        for(ii=0;ii<num;ii+=1)
182                hdrWave[start+ii] = char2num(lbl[ii])
183        endfor
184
185        return(0)
186End
187
188//works on the data in "type" folder
189//sums all of the data, and normalizes by the number of cells (=128*128)
190// calling procedure must make sure that the folder is on linear scale FIRST
191Function NormalizeDIV(type)
192        String type
193       
194        WAVE data=$("root:Packages:NIST:"+type+":data")
195        Variable totCts=sum(data,Inf,-Inf)              //sum all of the data
196       
197        data /= totCts
198        data *= 128*128
199       
200        return(0)
201End
202
203// prompts the user for the location of the "COR" -level data
204// data can be copied to any data folder (except DIV) for use here...
205//
206// then there is a "pause for user" to allow the user to select the "box"
207// in the ON-AXIS datset that is to be replaced by the data in the off-axis data
208//
209// corrections are done...
210//
211// finally, the DIV file is written to disk
212Function MakeDIVFile(ctrType,offType)
213        String ctrType,offType
214       
215        Prompt ctrType,"On-Center Plex data (corrected)",popup,"STO;SUB;BGD;COR;CAL;SAM;EMP;"
216        Prompt offType,"Offset Plex data (corrected)",popup,"STO;SUB;BGD;COR;CAL;SAM;EMP;"
217        DoPrompt "Pick the data types",ctrType,offType
218        //"COR" data in both places - reduction must be done ahead of time
219       
220        //temporarily set data display to linear
221        NVAR gLog = root:myGlobals:gLogScalingAsDefault
222        Variable oldState = gLog
223        gLog=0  //linear
224       
225        if(V_Flag==1)
226                //user cancelled
227                return(1)
228        endif
229       
230        //show the ctrType
231        //get the xy range to replace
232        Execute "ChangeDisplay(\""+ctrType+"\")"
233       
234        NewPanel/K=2/W=(139,341,382,432) as "Get XY Range"
235        DoWindow/C tmp_GetXY
236        AutoPositionWindow/E/M=1/R=SANS_Data
237        DrawText 15,20,"Find the (X1,X2) and (Y1,Y2) range to"
238        DrawText 15,40,"replace and press continue"
239        Button button0, pos={80,58},size={92,20},title="Continue"
240        Button button0,proc=XYContinueButtonProc
241       
242        PauseForUser tmp_GetXY,SANS_Data
243       
244        //replace the center section of the "on" data with the center of the "off" data
245        Variable x1,x2,y1,y2
246        GetXYRange(x1,x2,y1,y2)
247        Printf "X=(%d,%d)  Y=(%d,%d)\r", x1,x2,y1,y2
248        ReplaceDataBlock(ctrType,offType,x1,x2,y1,y2)
249       
250        DoAlert 1,"Is this NG1 data with a second beamstop?"
251        if(V_flag==1)
252                GetXYRange(x1,x2,y1,y2)
253                Printf "X=(%d,%d)  Y=(%d,%d)\r", x1,x2,y1,y2
254                ReplaceDataBlock(ctrType,offType,x1,x2,y1,y2)
255        endif
256       
257        //normalize the new data (and show it)
258        NormalizeDiv(ctrtype)
259        UpdateDisplayInformation(ctrtype)
260        //write out the new data file
261        WriteVAXWorkFile(ctrtype)
262        gLog = oldState         //set log/lin pref back to user - set preference
263        Return(0)
264End
265
266//ctrData is changed -- offData is not touched
267//simple replacement of the selected data...
268//
269Function ReplaceDataBlock(ctrType,offType,x1,x2,y1,y2)
270        String ctrType,offType
271        Variable x1,x2,y1,y2
272       
273        //do it crudely, with nested for loops
274        WAVE ctrData=$("root:Packages:NIST:"+ctrtype+":data")
275        WAVE offData=$("root:Packages:NIST:"+offtype+":data")
276        Variable ii,jj
277       
278        for(ii=x1;ii<=x2;ii+=1)
279                for(jj=y1;jj<=y2;jj+=1)
280                        ctrData[ii][jj] = offData[ii][jj]
281                endfor
282        endfor
283       
284        return(0)
285End
286
287//continue button waiting for the user to pick the range, and continue the execution
288//
289Function XYContinueButtonProc(ctrlName)
290        String ctrlName
291       
292        DoWindow/K tmp_GetXY
293End
294
295// prompts the user to enter the XY range for the box replacement
296// user can get these numbers by printing out marquee coordinates to the command window
297//
298Function GetXYRange(x1,x2,y1,y2)
299        Variable &x1,&x2,&y1,&y2
300       
301        Variable x1p,x2p,y1p,y2p
302        Prompt x1p,"X1"
303        Prompt x2p,"X2"
304        Prompt y1p,"Y1"
305        Prompt y2p,"Y2"
306        DoPrompt "Enter the range to replace",x1p,x2p,y1p,y2p
307        x1=x1p
308        x2=x2p
309        y1=y1p
310        y2=y2p
311       
312//      Print x1,x2,y1,y2
313        Return(0)
314End
Note: See TracBrowser for help on using the repository browser.