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

Last change on this file since 541 was 541, checked in by srkline, 14 years ago

(1) changes to ProDiv? to get the linear scaling correct with the new panel.

(2) bug fix in NCNR_Utils in file open dialog

(3) assorted changes to SASCALC and Simulation procedures to allow 1D simulation of data collection. 2D is now hidden and will be brought back later, as needed.

File size: 17.4 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
315
316
317/////////////////////
318//
319// for the DIV "protocol" panel, I probably need to have parts of the protocol panel initialized...
320// folders are generated at the startup initialization, before protocol panel
321//
322Proc BuildDIVPanel()
323        DoWindow/F DIV_Panel
324        if(V_flag==0)
325                InitDIVPanel()
326                DIV_Panel()
327        Endif
328End
329
330//initialization procedure for the protocol panel
331//note that :gAbsStr is also shared (common global) to that used in
332//the questionnare form of the protcol (see protocol.ipf)
333//
334//0901, uses 8 points in protocol wave
335Proc InitDIVPanel()
336
337        //set up the global variables needed for the protocol panel
338        //global strings to put in a temporary protocol textwave
339        Variable ii=0,nsteps=8
340        String waveStr="DIV_Protocol"
341        SetDataFolder root:myGlobals:Protocols
342        Make/O/T/N=(nsteps) $"root:myGlobals:Protocols:DIV_Protocol" = ""
343       
344        DIV_protocol[2] = "none"
345        DIV_protocol[3] = "none"
346        DIV_protocol[4] = "none"
347        DIV_protocol[5] = "AVTYPE=none;"
348        DIV_protocol[6] = "DRK=none,DRKMODE=0,"
349       
350
351        String/G root:myGlobals:Protocols:gPlex="Plex"
352        String/G root:myGlobals:Protocols:gPlexBgd="Bgd"
353        String/G root:myGlobals:Protocols:gPlexEmp="Emp"
354        String/G root:myGlobals:Protocols:gPlex_off="Plex offset"
355        String/G root:myGlobals:Protocols:gPlexBgd_off="Bgd offset"
356        String/G root:myGlobals:Protocols:gPlexEmp_off="Emp offset"
357        String/G root:myGlobals:Protocols:gPlexName="Plex_date.div"
358       
359        Variable/G root:myGlobals:Protocols:gPlexX1=45
360        Variable/G root:myGlobals:Protocols:gPlexX2=87
361        Variable/G root:myGlobals:Protocols:gPlexY1=43
362        Variable/G root:myGlobals:Protocols:gPlexY2=85
363        Variable/G root:myGlobals:Protocols:gPlexTrans=0.48
364       
365        SetDataFolder root:
366       
367End
368
369// load in one on-center file and show the box
370//
371Function ShowBoxButtonProc(ba) : ButtonControl
372        STRUCT WMButtonAction &ba
373
374        switch( ba.eventCode )
375                case 2: // mouse up
376                        // click code here
377                        //parse for the first run number
378                        SVAR gPlex = root:myGlobals:Protocols:gPlex
379                        String item,fname
380                       
381                        item = StringFromList(0, gPlex ,",")
382                        fname = FindFileFromRunNumber(str2num(item))
383                        if(strlen(fname) == 0)
384                                Abort "Bad file number in Plex field"
385                        endif
386                        // load the file
387                        ReadHeaderAndData(fname)        //this is the full Path+file
388                        UpdateDisplayInformation("RAW")
389                        //draw a box of the specified size. This is persistent on the display as you scroll to the offset data
390                        NVAR x1 = root:myGlobals:Protocols:gPlexX1
391                        NVAR x2 = root:myGlobals:Protocols:gPlexX2
392                        NVAR y1 = root:myGlobals:Protocols:gPlexY1
393                        NVAR y2 = root:myGlobals:Protocols:gPlexY2
394                       
395                        SetDrawLayer/W=SANS_Data/K UserFront                    //set the layer, and clear it
396                        SetDrawEnv/W=SANS_Data xcoord=bottom,ycoord=left,fillpat=0,linethick=3,linefgc=(65535, 65535, 65535)
397                        DrawRect/W=SANS_Data x1, y2, x2, y1
398                                               
399                        break
400        endswitch
401
402        return 0
403End
404
405// do everything...
406//
407Function GenerateDIVButtonProc(ba) : ButtonControl
408        STRUCT WMButtonAction &ba
409
410        switch( ba.eventCode )
411                case 2: // mouse up
412                        // click code here
413                       
414                        //temporarily set data display to linear
415                        NVAR gLog = root:myGlobals:gLogScalingAsDefault
416                        Variable oldState = gLog
417                        gLog=0  //linear
418                       
419                       
420                        SVAR gPlex = root:myGlobals:Protocols:gPlex
421                        SVAR gPlexBgd = root:myGlobals:Protocols:gPlexBgd
422                        SVAR gPlexEmp = root:myGlobals:Protocols:gPlexEmp
423                        SVAR gPlex_off = root:myGlobals:Protocols:gPlex_off
424                        SVAR gPlexBgd_off = root:myGlobals:Protocols:gPlexBgd_off
425                        SVAR gPlexEmp_off = root:myGlobals:Protocols:gPlexEmp_off
426                        SVAR gPlexName = root:myGlobals:Protocols:gPlexName
427                       
428                        NVAR X1 = root:myGlobals:Protocols:gPlexX1
429                        NVAR X2 = root:myGlobals:Protocols:gPlexX2
430                        NVAR Y1 = root:myGlobals:Protocols:gPlexY1
431                        NVAR Y2 = root:myGlobals:Protocols:gPlexY2
432                        NVAR gPlexTrans = root:myGlobals:Protocols:gPlexTrans
433                       
434                        WAVE/T proto = $"root:myGlobals:Protocols:DIV_Protocol"
435                       
436                        String item,fname,str
437                        Variable ii,num
438                // reduce the on-center
439                        //patch trans
440                        num = ItemsInList(gPlex, ",")
441                        for(ii=0;ii<num;ii+=1)
442                                item = StringFromList(ii, gPlex ,",")
443                                fname = FindFileFromRunNumber(str2num(item))
444                                if(strlen(fname) == 0)
445                                        Abort "Bad file number in no offset Plex field"
446                                endif
447                                WriteTransmissionToHeader(fname,gPlexTrans)
448                        endfor
449                       
450                        //go through the protocol
451                        str = ParseRunNumberList(gPlexBgd)
452                        if(strlen(str) > 0)
453                                proto[0] = str
454                        else
455                                Abort "Bad file number in no offset Bgd"
456                        endif
457                        str = ParseRunNumberList(gPlexEmp)
458                        if(strlen(str) > 0)
459                                proto[1] = str
460                        else
461                                Abort "Bad file number in no offset Emp"
462                        endif
463                        str = ParseRunNumberList(gPlex)
464                        if(strlen(str) > 0)
465                                ExecuteProtocol("root:myGlobals:Protocols:DIV_Protocol",str)
466                        else
467                                Abort "Bad file number in no offset Plex"
468                        endif
469                        // move it into STO
470                        Execute "CopyWorkFolder(\"COR\",\"STO\")"
471                       
472                       
473                       
474                // reduce the off-center, keep in STO
475                        //patch trans
476                        num = ItemsInList(gPlex_off, ",")
477                        for(ii=0;ii<num;ii+=1)
478                                item = StringFromList(ii, gPlex_off ,",")
479                                fname = FindFileFromRunNumber(str2num(item))
480                                if(strlen(fname) == 0)
481                                        Abort "Bad file number in Plex field"
482                                endif
483                                WriteTransmissionToHeader(fname,gPlexTrans)
484                        endfor
485                       
486                        //go through the protocol
487                        str = ParseRunNumberList(gPlexBgd_off)
488                        if(strlen(str) > 0)
489                                proto[0] = str
490                        else
491                                Abort "Bad file number in offset Bgd"
492                        endif
493                        str = ParseRunNumberList(gPlexEmp_off)
494                        if(strlen(str) > 0)
495                                proto[1] = str
496                        else
497                                Abort "Bad file number in offset Emp"
498                        endif
499                        str = ParseRunNumberList(gPlex_off)
500                        if(strlen(str) > 0)
501                                ExecuteProtocol("root:myGlobals:Protocols:DIV_Protocol",str)
502                        else
503                                Abort "Bad file number in offset Emp"
504                        endif
505                        ConvertFolderToLinearScale("COR")
506                       
507                       
508                // replace the patch
509                // on-center data is changed (STO)
510                        ReplaceDataBlock("STO","COR",x1,x2,y1,y2)
511                // normalize
512                        NormalizeDiv("STO")
513                        UpdateDisplayInformation("STO")
514                //write out the new data file
515                        WriteVAXWorkFile("STO")
516                               
517                        gLog=oldState           //revert display preference to old state       
518                        break
519        endswitch
520
521        return 0
522End
523
524// if a dark color is used, then
525//¥SetVariable setvar0 labelBack=(65535,65535,65535)
526// for each variable will give a white background to the label text
527Window DIV_Panel() : Panel
528        PauseUpdate; Silent 1           // building window...
529        NewPanel /W=(594,44,932,570)/K=1 as "DIV_Panel"
530//      ModifyPanel cbRGB=(35867,28177,65535)           //purple
531//      ModifyPanel cbRGB=(1,16019,65535)                               //electric blue
532        ModifyPanel cbRGB=(36631,59604,33902)           //spring green
533        SetDrawLayer UserBack
534        DrawRect 71,324,145,391
535        TitleBox title0,pos={14,16},size={50,20},title="No Offset"
536        TitleBox title0_1,pos={17,125},size={35,20},title="Offset"
537        SetVariable setvar0,pos={15,46},size={250,15},title="PLEX",value= root:myGlobals:Protocols:gPlex
538        SetVariable setvar0_1,pos={16,69},size={250,15},title="EMP",value= root:myGlobals:Protocols:gPlexEmp
539        SetVariable setvar0_2,pos={14,92},size={250,15},title="BGD",value= root:myGlobals:Protocols:gPlexBgd
540        SetVariable setvar1,pos={17,158},size={250,15},title="PLEX",value= root:myGlobals:Protocols:gPlex_off
541        SetVariable setvar001,pos={18,181},size={250,15},title="EMP",value= root:myGlobals:Protocols:gPlexEmp_off
542        SetVariable setvar002,pos={16,204},size={250,15},title="BGD",value= root:myGlobals:Protocols:gPlexBgd_off
543        SetVariable setvar002_1,pos={14,251},size={150,15},title="Transmission"
544        SetVariable setvar002_1,limits={0,1,0.01},value= root:myGlobals:Protocols:gPlexTrans
545//      SetVariable setvar003,pos={16,441},size={250,15},title="DIV FILE NAME"
546//      SetVariable setvar003,value= root:myGlobals:Protocols:gPlexName
547        Button button0,pos={226,325},size={90,20},proc=ShowBoxButtonProc,title="Show Box"
548        Button button1,pos={25,441},size={150,20},proc=GenerateDIVButtonProc,title="Generate DIV File"
549        Button button2,pos={25,481},size={150,20},proc=ReloadDIVButtonProc,title="Load DIV File"
550        Button button3,pos={240,10},size={50,20},proc=DIVHelpButtonProc,title="Help"
551        SetVariable setvar00201,pos={84,297},size={50,15},limits={0,128,1},title=" ",value= root:myGlobals:Protocols:gPlexY2
552        SetVariable setvar00202,pos={15,350},size={50,15},limits={0,128,1},title=" ",value= root:myGlobals:Protocols:gPlexX1
553        SetVariable setvar00203,pos={85,399},size={50,15},limits={0,128,1},title=" ",value= root:myGlobals:Protocols:gPlexY1
554        SetVariable setvar00204,pos={156,348},size={50,15},limits={0,128,1},title=" ",value= root:myGlobals:Protocols:gPlexX2
555EndMacro
556
557
558// load in a DIV file, print out the stats, display in SANS_Data
559//
560Function ReloadDIVButtonProc(ba) : ButtonControl
561        STRUCT WMButtonAction &ba
562
563        switch( ba.eventCode )
564                case 2: // mouse up
565                        // click code here
566                        Execute "ReadWork_DIV()"
567                        WaveStats root:Packages:NIST:DIV:data
568                        Print "*"                       
569//                      Execute "ChangeDisplay(\"DIV\")"       
570                        break
571        endswitch
572
573        return 0
574End
575
576//
577Function DIVHelpButtonProc(ba) : ButtonControl
578        STRUCT WMButtonAction &ba
579
580        switch( ba.eventCode )
581                case 2: // mouse up
582                        // click code here
583                        DisplayHelpTopic/Z/K=1 "SANS Data Reduction Tutorial[Detector Sensitivity File]"
584                        if(V_flag !=0)
585                                DoAlert 0,"The SANS Data Reduction Tutorial Help file could not be found"
586                        endif
587                        break
588        endswitch
589
590        return 0
591End
Note: See TracBrowser for help on using the repository browser.