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

Last change on this file since 715 was 665, checked in by srkline, 13 years ago

Made preferences a common panel (moved to PlotUtilsMacro?.ipf and globals to root:Packages:NIST:) and added menu items for all packages. Many files had to be modified so that the preferences could be properly accessed

File Open dialog now is set to "All files" so that XML can be selected. I think that all open access that doesn't already have the full path go through this common function.

File size: 17.2 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=5.0
3#pragma IgorVersion=6.1
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// Oct 2009 - SRK - pulled out the writing of the data file to NCNR_DataReadWrite.ipf
24//      leaving a stub Write_DIV_File() for the writer. Fully corrected, patched, and normalized DIV data
25//      is written out from "type" folder. The DIV file written out must be written in a
26//      format that is readable by ReadHeaderAndWork(type,fname). Each facility gets to pick their own format.
27//
28//      no longer hard-wired to 128x128
29//
30//*********************
31
32
33//works on the data in "type" folder
34//sums all of the data, and normalizes by the number of cells (=pixelX*pixelY)
35// calling procedure must make sure that the folder is on linear scale FIRST
36Function NormalizeDIV(type)
37        String type
38       
39        WAVE data=$("root:Packages:NIST:"+type+":data")
40        Variable totCts=sum(data,Inf,-Inf)              //sum all of the data
41        NVAR pixelX = root:myGlobals:gNPixelsX
42        NVAR pixelY = root:myGlobals:gNPixelsY
43
44       
45        data /= totCts
46        data *= pixelX*pixelY
47       
48        return(0)
49End
50
51// prompts the user for the location of the "COR" -level data
52// data can be copied to any data folder (except DIV) for use here...
53//
54// then there is a "pause for user" to allow the user to select the "box"
55// in the ON-AXIS datset that is to be replaced by the data in the off-axis data
56//
57// corrections are done...
58//
59// finally, the DIV file is written to disk
60Function MakeDIVFile(ctrType,offType)
61        String ctrType,offType
62       
63        Prompt ctrType,"On-Center Plex data (corrected)",popup,"STO;SUB;BGD;COR;CAL;SAM;EMP;"
64        Prompt offType,"Offset Plex data (corrected)",popup,"STO;SUB;BGD;COR;CAL;SAM;EMP;"
65        DoPrompt "Pick the data types",ctrType,offType
66        //"COR" data in both places - reduction must be done ahead of time
67       
68        //temporarily set data display to linear
69        NVAR gLog = root:Packages:NIST:gLogScalingAsDefault
70        Variable oldState = gLog
71        gLog=0  //linear
72       
73        if(V_Flag==1)
74                //user cancelled
75                return(1)
76        endif
77
78#if (exists("QUOKKA")==6)
79        //corrects edge rows and columns by copy data from adjacent column
80        DoAlert 1,"Do edge correction for Quokka detector?"
81        if(V_flag==1)
82                DoEdgeCorrection(ctrType)
83                DoEdgeCorrection(offType)               
84        endif
85#endif
86       
87        //show the ctrType
88        //get the xy range to replace
89        Execute "ChangeDisplay(\""+ctrType+"\")"
90       
91        NewPanel/K=2/W=(139,341,382,432) as "Get XY Range"
92        DoWindow/C tmp_GetXY
93        AutoPositionWindow/E/M=1/R=SANS_Data
94        DrawText 15,20,"Find the (X1,X2) and (Y1,Y2) range to"
95        DrawText 15,40,"replace and press continue"
96        Button button0, pos={80,58},size={92,20},title="Continue"
97        Button button0,proc=XYContinueButtonProc
98       
99        PauseForUser tmp_GetXY,SANS_Data
100       
101        //replace the center section of the "on" data with the center of the "off" data
102        Variable x1,x2,y1,y2
103        GetXYRange(x1,x2,y1,y2)
104        Printf "X=(%d,%d)  Y=(%d,%d)\r", x1,x2,y1,y2
105        ReplaceDataBlock(ctrType,offType,x1,x2,y1,y2)
106       
107        DoAlert 1,"Is this NG1 data with a second beamstop?"
108        if(V_flag==1)
109                GetXYRange(x1,x2,y1,y2)
110                Printf "X=(%d,%d)  Y=(%d,%d)\r", x1,x2,y1,y2
111                ReplaceDataBlock(ctrType,offType,x1,x2,y1,y2)
112        endif
113       
114        //normalize the new data (and show it)
115        NormalizeDiv(ctrtype)
116        UpdateDisplayInformation(ctrtype)
117        //write out the new data file
118        Write_DIV_File(ctrtype)
119        gLog = oldState         //set log/lin pref back to user - set preference
120        Return(0)
121End
122
123//ctrData is changed -- offData is not touched
124//simple replacement of the selected data...
125//
126// working in detector coordinates
127Function ReplaceDataBlock(ctrType,offType,x1,x2,y1,y2)
128        String ctrType,offType
129        Variable x1,x2,y1,y2
130       
131        //do it crudely, with nested for loops
132        WAVE ctrData=$("root:Packages:NIST:"+ctrtype+":data")
133        WAVE offData=$("root:Packages:NIST:"+offtype+":data")
134        Variable ii,jj
135       
136        for(ii=x1;ii<=x2;ii+=1)
137                for(jj=y1;jj<=y2;jj+=1)
138                        ctrData[ii][jj] = offData[ii][jj]
139                endfor
140        endfor
141       
142        return(0)
143End
144
145//continue button waiting for the user to pick the range, and continue the execution
146//
147Function XYContinueButtonProc(ctrlName)
148        String ctrlName
149       
150        DoWindow/K tmp_GetXY
151End
152
153// prompts the user to enter the XY range for the box replacement
154// user can get these numbers by printing out marquee coordinates to the command window
155//
156Function GetXYRange(x1,x2,y1,y2)
157        Variable &x1,&x2,&y1,&y2
158       
159        Variable x1p,x2p,y1p,y2p
160        Prompt x1p,"X1"
161        Prompt x2p,"X2"
162        Prompt y1p,"Y1"
163        Prompt y2p,"Y2"
164        DoPrompt "Enter the range to replace",x1p,x2p,y1p,y2p
165        x1=x1p
166        x2=x2p
167        y1=y1p
168        y2=y2p
169       
170//      Print x1,x2,y1,y2
171        Return(0)
172End
173
174
175/////////////////////
176//
177// for the DIV "protocol" panel, I probably need to have parts of the protocol panel initialized...
178// folders are generated at the startup initialization, before protocol panel
179//
180Proc BuildDIVPanel()
181        DoWindow/F DIV_Panel
182        if(V_flag==0)
183                InitDIVPanel()
184                DIV_Panel()
185        Endif
186End
187
188//initialization procedure for the protocol panel
189//note that :gAbsStr is also shared (common global) to that used in
190//the questionnare form of the protcol (see protocol.ipf)
191//
192//0901, uses 8 points in protocol wave
193Proc InitDIVPanel()
194
195        //set up the global variables needed for the protocol panel
196        //global strings to put in a temporary protocol textwave
197        Variable ii=0,nsteps=8
198        String waveStr="DIV_Protocol"
199        SetDataFolder root:myGlobals:Protocols
200        Make/O/T/N=(nsteps) $"root:myGlobals:Protocols:DIV_Protocol" = ""
201       
202        DIV_protocol[2] = "none"
203        DIV_protocol[3] = "none"
204        DIV_protocol[4] = "none"
205        DIV_protocol[5] = "AVTYPE=none;"
206        DIV_protocol[6] = "DRK=none,DRKMODE=0,"
207       
208
209        String/G root:myGlobals:Protocols:gPlex="Plex"
210        String/G root:myGlobals:Protocols:gPlexBgd="Bgd"
211        String/G root:myGlobals:Protocols:gPlexEmp="Emp"
212        String/G root:myGlobals:Protocols:gPlex_off="Plex offset"
213        String/G root:myGlobals:Protocols:gPlexBgd_off="Bgd offset"
214        String/G root:myGlobals:Protocols:gPlexEmp_off="Emp offset"
215        String/G root:myGlobals:Protocols:gPlexName="Plex_date.div"
216       
217        Variable/G root:myGlobals:Protocols:gPlexX1=45
218        Variable/G root:myGlobals:Protocols:gPlexX2=87
219        Variable/G root:myGlobals:Protocols:gPlexY1=43
220        Variable/G root:myGlobals:Protocols:gPlexY2=85
221        Variable/G root:myGlobals:Protocols:gPlexTrans=0.48
222       
223        SetDataFolder root:
224       
225End
226
227// load in one on-center file and show the box
228//
229Function ShowBoxButtonProc(ba) : ButtonControl
230        STRUCT WMButtonAction &ba
231
232        switch( ba.eventCode )
233                case 2: // mouse up
234                        // click code here
235                        if(cmpstr(ba.ctrlName, "ShowBox") == 0)
236                       
237                                //parse for the first run number
238                                SVAR gPlex = root:myGlobals:Protocols:gPlex
239                                String item,fname
240                               
241                                item = StringFromList(0, gPlex ,",")
242                                fname = FindFileFromRunNumber(str2num(item))
243                                if(strlen(fname) == 0)
244                                        Abort "Bad file number in Plex field"
245                                endif
246                                // load the file
247                                ReadHeaderAndData(fname)        //this is the full Path+file
248                                UpdateDisplayInformation("RAW")
249                                //draw a box of the specified size. This is persistent on the display as you scroll to the offset data
250                                NVAR x1 = root:myGlobals:Protocols:gPlexX1
251                                NVAR x2 = root:myGlobals:Protocols:gPlexX2
252                                NVAR y1 = root:myGlobals:Protocols:gPlexY1
253                                NVAR y2 = root:myGlobals:Protocols:gPlexY2
254                               
255                                SetDrawLayer/W=SANS_Data/K UserFront                    //set the layer, and clear it
256                                SetDrawEnv/W=SANS_Data xcoord=bottom,ycoord=left,fillpat=0,linethick=3,linefgc=(65535, 65535, 65535)
257                                DrawRect/W=SANS_Data x1, y2, x2, y1
258                               
259                                Button $ba.ctrlName,title="Clear Box",rename=HideBox,win=DIV_Panel
260                               
261                        else
262                                if(winType("SANS_Data")==1)
263                                        SetDrawLayer/W=SANS_Data/K UserFront                    //set the layer, and clear it
264                                        Button $ba.ctrlName,title="Show Box",rename=ShowBox,win=DIV_Panel
265                                else
266                                        Button $ba.ctrlName,title="Show Box",rename=ShowBox,win=DIV_Panel
267                                endif
268                        endif   
269                       
270                        break
271        endswitch
272
273        return 0
274End
275
276// do everything...
277//
278Function GenerateDIVButtonProc(ba) : ButtonControl
279        STRUCT WMButtonAction &ba
280
281        Variable err=0
282       
283        switch( ba.eventCode )
284                case 2: // mouse up
285                        // click code here
286                       
287                        //temporarily set data display to linear
288                        NVAR gLog = root:Packages:NIST:gLogScalingAsDefault
289                        Variable oldState = gLog
290                        gLog=0  //linear
291                       
292                       
293                        SVAR gPlex = root:myGlobals:Protocols:gPlex
294                        SVAR gPlexBgd = root:myGlobals:Protocols:gPlexBgd
295                        SVAR gPlexEmp = root:myGlobals:Protocols:gPlexEmp
296                        SVAR gPlex_off = root:myGlobals:Protocols:gPlex_off
297                        SVAR gPlexBgd_off = root:myGlobals:Protocols:gPlexBgd_off
298                        SVAR gPlexEmp_off = root:myGlobals:Protocols:gPlexEmp_off
299                        SVAR gPlexName = root:myGlobals:Protocols:gPlexName
300                       
301                        NVAR X1 = root:myGlobals:Protocols:gPlexX1
302                        NVAR X2 = root:myGlobals:Protocols:gPlexX2
303                        NVAR Y1 = root:myGlobals:Protocols:gPlexY1
304                        NVAR Y2 = root:myGlobals:Protocols:gPlexY2
305                        NVAR gPlexTrans = root:myGlobals:Protocols:gPlexTrans
306                       
307                        WAVE/T proto = $"root:myGlobals:Protocols:DIV_Protocol"
308                       
309                        String item,fname,str
310                        Variable ii,num
311                // reduce the on-center
312                        //patch trans
313                        num = ItemsInList(gPlex, ",")
314                        for(ii=0;ii<num;ii+=1)
315                                item = StringFromList(ii, gPlex ,",")
316                                fname = FindFileFromRunNumber(str2num(item))
317                                if(strlen(fname) == 0)
318                                        Abort "Bad file number in no offset Plex field"
319                                endif
320                                WriteTransmissionToHeader(fname,gPlexTrans)
321                        endfor
322                       
323                        //go through the protocol
324                        str = ParseRunNumberList(gPlexBgd)
325                        if(strlen(str) > 0)
326                                proto[0] = str
327                        else
328                                Abort "Bad file number in no offset Bgd"
329                        endif
330                        str = ParseRunNumberList(gPlexEmp)
331                        if(strlen(str) > 0)
332                                proto[1] = str
333                                err = CheckDIVBeamCenter(str,65,65)
334                                if(err)
335                                        Abort "On-center EMP files do not have correct beam center"
336                                endif
337                        else
338                                Abort "Bad file number in no offset Emp"
339                        endif
340                        str = ParseRunNumberList(gPlex)
341                        if(strlen(str) > 0)
342                                err = CheckDIVBeamCenter(str,65,65)
343                                if(err)
344                                        Abort "On-center PLEX files do not have correct beam center"
345                                endif
346                                ExecuteProtocol("root:myGlobals:Protocols:DIV_Protocol",str)
347                        else
348                                Abort "Bad file number in no offset Plex"
349                        endif
350                        // move it into STO
351                        Execute "CopyWorkFolder(\"COR\",\"STO\")"
352                       
353                       
354                       
355                // reduce the off-center, keep in STO
356                        //patch trans
357                        num = ItemsInList(gPlex_off, ",")
358                        for(ii=0;ii<num;ii+=1)
359                                item = StringFromList(ii, gPlex_off ,",")
360                                fname = FindFileFromRunNumber(str2num(item))
361                                if(strlen(fname) == 0)
362                                        Abort "Bad file number in Plex field"
363                                endif
364                                WriteTransmissionToHeader(fname,gPlexTrans)
365                        endfor
366                       
367                        //go through the protocol
368                        str = ParseRunNumberList(gPlexBgd_off)
369                        if(strlen(str) > 0)
370                                proto[0] = str
371                        else
372                                Abort "Bad file number in offset Bgd"
373                        endif
374                        str = ParseRunNumberList(gPlexEmp_off)
375                        if(strlen(str) > 0)
376                                proto[1] = str
377                                err = CheckDIVBeamCenter(str,105,65)
378                                if(err)
379                                        Abort "Off-center EMP files do not have correct beam center"
380                                endif
381                        else
382                                Abort "Bad file number in offset Emp"
383                        endif
384                        str = ParseRunNumberList(gPlex_off)
385                        if(strlen(str) > 0)
386                                err = CheckDIVBeamCenter(str,105,65)
387                                if(err)
388                                        Abort "On-center EMP files do not have correct beam center"
389                                endif
390                                ExecuteProtocol("root:myGlobals:Protocols:DIV_Protocol",str)
391                        else
392                                Abort "Bad file number in offset Emp"
393                        endif
394                        ConvertFolderToLinearScale("COR")
395                       
396#if (exists("QUOKKA")==6)
397                        //corrects edge rows and columns by copy data from adjacent column
398                        String ctrType="STO",offType="COR"
399                        DoAlert 1,"Do edge correction for Quokka detector?"
400                        if(V_flag==1)
401                                DoEdgeCorrection(ctrType)
402                                DoEdgeCorrection(offType)               
403                        endif
404#endif
405                       
406                // replace the patch
407                // on-center data is changed (STO)
408                        ReplaceDataBlock("STO","COR",x1,x2,y1,y2)
409                // normalize
410                        NormalizeDiv("STO")
411                        UpdateDisplayInformation("STO")
412                //write out the new data file
413                        Write_DIV_File("STO")
414                               
415                        gLog=oldState           //revert display preference to old state       
416                        break
417        endswitch
418
419        return 0
420End
421
422// if a dark color is used, then
423//¥SetVariable setvar0 labelBack=(65535,65535,65535)
424// for each variable will give a white background to the label text
425Proc DIV_Panel()
426        PauseUpdate; Silent 1           // building window...
427        NewPanel /W=(594,44,932,570)/K=1 as "DIV_Panel"
428        DoWindow/C DIV_Panel
429//      ModifyPanel cbRGB=(35867,28177,65535)           //purple
430//      ModifyPanel cbRGB=(1,16019,65535)                               //electric blue
431        ModifyPanel cbRGB=(36631,59604,33902)           //spring green
432        SetDrawLayer UserBack
433        DrawRect 71,324,145,391
434        TitleBox title0,pos={14,16},size={50,20},title="No Offset"
435        TitleBox title0_1,pos={17,125},size={35,20},title="Offset"
436        SetVariable setvar0,pos={15,46},size={250,15},title="PLEX",value= root:myGlobals:Protocols:gPlex
437        SetVariable setvar0_1,pos={16,69},size={250,15},title="EMP",value= root:myGlobals:Protocols:gPlexEmp
438        SetVariable setvar0_2,pos={14,92},size={250,15},title="BGD",value= root:myGlobals:Protocols:gPlexBgd
439        SetVariable setvar1,pos={17,158},size={250,15},title="PLEX",value= root:myGlobals:Protocols:gPlex_off
440        SetVariable setvar001,pos={18,181},size={250,15},title="EMP",value= root:myGlobals:Protocols:gPlexEmp_off
441        SetVariable setvar002,pos={16,204},size={250,15},title="BGD",value= root:myGlobals:Protocols:gPlexBgd_off
442        SetVariable setvar002_1,pos={14,251},size={150,15},title="Transmission"
443        SetVariable setvar002_1,limits={0,1,0.01},value= root:myGlobals:Protocols:gPlexTrans
444//      SetVariable setvar003,pos={16,441},size={250,15},title="DIV FILE NAME"
445//      SetVariable setvar003,value= root:myGlobals:Protocols:gPlexName
446        Button ShowBox,pos={226,325},size={90,20},proc=ShowBoxButtonProc,title="Show Box"
447        Button button1,pos={25,430},size={150,20},proc=GenerateDIVButtonProc,title="Generate DIV File"
448        Button button2,pos={25,460},size={150,20},proc=ReloadDIVButtonProc,title="Load DIV File"
449        Button button4,pos={240,481},size={80,20},proc=DoneDIVButtonProc,title="Done"
450        Button button3,pos={240,10},size={50,20},proc=DIVHelpButtonProc,title="Help"
451        Button button5,pos={25,490},size={150,20},proc=CompareDIVButtonProc,title="Compare DIV Files"
452        SetVariable setvar00201,pos={84,297},size={50,15},limits={0,root:myGlobals:gNPixelsY-1,1},title=" ",value= root:myGlobals:Protocols:gPlexY2
453        SetVariable setvar00202,pos={15,350},size={50,15},limits={0,root:myGlobals:gNPixelsX-1,1},title=" ",value= root:myGlobals:Protocols:gPlexX1
454        SetVariable setvar00203,pos={85,399},size={50,15},limits={0,root:myGlobals:gNPixelsY-1,1},title=" ",value= root:myGlobals:Protocols:gPlexY1
455        SetVariable setvar00204,pos={156,348},size={50,15},limits={0,root:myGlobals:gNPixelsX-1,1},title=" ",value= root:myGlobals:Protocols:gPlexX2
456EndMacro
457
458
459// done
460//
461Function DoneDIVButtonProc(ba) : ButtonControl
462        STRUCT WMButtonAction &ba
463
464        switch( ba.eventCode )
465                case 2: // mouse up
466                        // click code here
467                        DoWindow/K DIV_Panel
468                        break
469        endswitch
470
471        return 0
472End
473
474// load in a DIV file, print out the stats, display in SANS_Data
475//
476Function ReloadDIVButtonProc(ba) : ButtonControl
477        STRUCT WMButtonAction &ba
478
479        switch( ba.eventCode )
480                case 2: // mouse up
481                        // click code here
482                        Execute "ReadWork_DIV()"
483                        WaveStats root:Packages:NIST:DIV:data
484                        Print "*"                       
485//                      Execute "ChangeDisplay(\"DIV\")"       
486                        break
487        endswitch
488
489        return 0
490End
491
492//
493Function DIVHelpButtonProc(ba) : ButtonControl
494        STRUCT WMButtonAction &ba
495
496        switch( ba.eventCode )
497                case 2: // mouse up
498                        // click code here
499                        DisplayHelpTopic/Z/K=1 "SANS Data Reduction Tutorial[Detector Sensitivity File]"
500                        if(V_flag !=0)
501                                DoAlert 0,"The SANS Data Reduction Tutorial Help file could not be found"
502                        endif
503                        break
504        endswitch
505
506        return 0
507End
508
509// load in two DIV files, divide them, and display the results
510// first is divided by the second, results are in SUB
511//
512Function CompareDIVButtonProc(ba) : ButtonControl
513        STRUCT WMButtonAction &ba
514
515        switch( ba.eventCode )
516                case 2: // mouse up
517                        // click code here
518                        DoAlert 0,"First DIV / Second DIV = Result in SUB folder"
519                       
520                        Execute "ReadWork_DIV()"
521                        Execute "CopyWorkContents(\"DIV\",\"STO\")"             // converts linear, copies data, kills linear_data
522                        Execute "CopyWorkContents(\"DIV\",\"SUB\")"             ///just to have waves for later
523
524                        Execute "ReadWork_DIV()"
525                        Execute "CopyWorkContents(\"DIV\",\"DRK\")"             //then data in DRK is guaranteed linear
526
527                        WAVE sub_d = root:Packages:NIST:SUB:data
528                        WAVE sto_d = root:Packages:NIST:STO:data
529                        WAVE drk_d = root:Packages:NIST:DRK:data
530                       
531                        sub_d = sto_d/drk_d
532
533//                      WaveStats root:Packages:NIST:DIV:data
534//                      Print "*"                       
535                        Execute "ChangeDisplay(\"SUB\")"       
536                        break
537        endswitch
538
539        return 0
540End
541Function CompareDIV()
542
543        STRUCT WMButtonAction ba
544
545        ba.eventCode=2
546        CompareDIVButtonProc(ba)
547        return(0)
548End
549
550//loop through each file and check the x and y center
551// within some tolerance (5 pixels) should be fine
552Function CheckDIVBeamCenter(str,xc,yc)
553        String str
554        Variable xc,yc
555       
556        Variable err,ii,num,tmpX,tmpY,badCtr,tol=5
557        String fileStr,pathStr
558       
559        PathInfo catPathName
560        pathStr=S_path
561       
562        num = ItemsInList(str,",")
563        ii=0
564        badCtr = 0
565        do
566                fileStr = pathStr + StringFromList(ii, str,",")
567                tmpX = GetBeamXPos(fileStr)
568                tmpY = GetBeamYPos(fileStr)
569                if(abs(tmpX - xc) > tol)
570                        badCtr = 1
571                endif
572                if(abs(tmpY - yc) > tol)
573                        badCtr = 1
574                endif           
575                ii+=1
576        while(ii<num && !badCtr)
577       
578        return(badCtr)
579//      return(0)
580end
Note: See TracBrowser for help on using the repository browser.