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

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

Several changes:
1) added /I=1 flag in several places (mostly the invariant) so that the error wave would be interpreted as the standard deviation, not 1/s (Jae_Hie pointed this out)
2) put error checking in ProDiv? to warn if the pixel centers are more than 5 pixels from the expected 65,65 for on-center or 105,65 for the offset (usually run at 20 cm offset)
3) commented out the line in WriteQIS that outputs 2D resolution information to QxQy? data. I just don't think it's correct yet, and the 2D resolution smearing is not ready either.

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:myGlobals: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:myGlobals: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)
579end
Note: See TracBrowser for help on using the repository browser.