source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS/WorkFileUtils.ipf @ 683

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

Corrections to NSORT and CombineFiles? to work with XML i/o.

CombineFiles? table hook now is properly active only in the upper table.

Some file filtering functions have been streamlined, but are still somewhat redundant, and could be consolidated. These are whenever listing of reduced files is requested (filter out what is known to be something else)

Commented out print statements from XML reader.

File size: 44.6 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=5.0
3#pragma IgorVersion=6.1
4
5//*******************
6// Vers 1.2 100901
7//
8//*******************
9// Utility procedures for handling of workfiles (each is housed in a separate datafolder)
10//
11// - adding data to a workfile
12// - copying workfiles to another folder
13//
14// - absolute scaling
15// - DIV detector sensitivity corrections
16//
17// - the WorkFile Math panel for simple image math
18// -
19// - adding work.drk data without normalizing to monitor counts
20//***************************
21
22
23//testing procedure, not called anymore
24Proc Add_to_Workfile(type, add)
25        String type,add
26        Prompt type,"WORK data type",popup,"SAM;EMP;BGD"
27        Prompt add,"Add to current WORK contents?",popup,"No;Yes"
28       
29        //macro will take whatever is in RAW folder and "ADD" it to the folder specified
30        //in the popup menu
31       
32        //"add" = yes/no, don't add to previous runs
33        //switch here - two separate functions to avoid (my) confusion
34        Variable err
35        if(cmpstr(add,"No")==0)
36                //don't add to prev work contents, copy RAW contents to work and convert
37                err = Raw_to_work(type)
38        else
39                //yes, add RAW to the current work folder contents
40                err = Add_raw_to_work(type)
41        endif
42       
43        String newTitle = "WORK_"+type
44        DoWindow/F SANS_Data
45        DoWindow/T SANS_Data, newTitle
46        KillStrings/Z newTitle
47       
48        //need to update the display with "data" from the correct dataFolder
49        fRawWindowHook()
50       
51End
52
53//will "ADD" the current contents of the RAW folder to the newType work folder
54//and will ADD the RAW contents to the existing content of the newType folder
55// - used when adding multiple runs together
56//(the function Raw_to_work(type) makes a fresh workfile)
57//
58//the current display type is updated to newType (global)
59Function Add_raw_to_work(newType)
60        String newType
61               
62        String destPath=""
63       
64        // if the desired workfile doesn't exist, let the user know, and just make a new one
65        destPath = "root:Packages:NIST:"+newType + ":data"
66        if(WaveExists($destpath) == 0)
67                Print "There is no old work file to add to - a new one will be created"
68                //call Raw_to_work(), then return from this function
69                Raw_to_Work(newType)
70                Return(0)               //does not generate an error - a single file was converted to work.newtype
71        Endif
72       
73        NVAR pixelsX = root:myGlobals:gNPixelsX
74        NVAR pixelsY = root:myGlobals:gNPixelsY
75       
76        //now make references to data in newType folder
77        DestPath="root:Packages:NIST:"+newType 
78        WAVE data=$(destPath +":data")                  // these wave references point to the EXISTING work data
79        WAVE/T textread=$(destPath + ":textread")
80        WAVE integersread=$(destPath + ":integersread")
81        WAVE realsread=$(destPath + ":realsread")
82       
83        Variable deadTime,defmon,total_mon,total_det,total_trn,total_numruns,total_rtime
84        Variable ii,jj,itim,cntrate,dscale,scale,uscale,wrk_beamx,wrk_beamy,xshift,yshift
85
86// 08/01 detector constants are now returned from a function, based on the detector type and beamline
87//      dt_ornl = 3.4e-6                //deadtime of Ordella detectors as of 30-AUG-99
88//      dt_ill=3.0e-6                   //Cerca detector deadtime constant as of 30-AUG-99
89
90        defmon=1e8                      //default monitor counts
91       
92        //Yes, add to previous run(s) in work, that does exist
93        //use the actual monitor count run.savmon rather than the normalized monitor count
94        //in run.moncnt and unscale the work data
95       
96        total_mon = realsread[1]        //saved monitor count
97        uscale = total_mon/defmon               //unscaling factor
98        total_det = uscale*realsread[2]         //unscaled detector count
99        total_trn = uscale*realsread[39]        //unscaled trans det count
100        total_numruns = integersread[3] //number of runs in workfile
101        total_rtime = integersread[2]           //total counting time in workfile
102        //retrieve workfile beamcenter
103        wrk_beamx = realsread[16]
104        wrk_beamy = realsread[17]
105        //unscale the workfile data in "newType"
106        //
107        //check for log-scaling and adjust if necessary
108        ConvertFolderToLinearScale(newType)
109        //
110        //then unscale the data array
111        data *= uscale
112       
113        //DetCorr() has not been applied to the data in RAW , do it now in a local reference to the raw data
114        WAVE raw_data = $"root:Packages:NIST:RAW:data"
115        WAVE raw_reals =  $"root:Packages:NIST:RAW:realsread"
116        WAVE/T raw_text = $"root:Packages:NIST:RAW:textread"
117        WAVE raw_ints = $"root:Packages:NIST:RAW:integersread"
118       
119        //check for log-scaling of the raw data - make sure it's linear
120        ConvertFolderToLinearScale("RAW")
121       
122        // switches to control what is done, don't do the transmission correction for the BGD measurement
123        NVAR doEfficiency = root:Packages:NIST:gDoDetectorEffCorr
124        NVAR gDoTrans = root:Packages:NIST:gDoTransmissionCorr
125        Variable doTrans = gDoTrans
126        if(cmpstr("BGD",newtype) == 0)
127                doTrans = 0             //skip the trans correction for the BGD file but don't change the value of the global
128        endif   
129       
130        DetCorr(raw_data,raw_reals,doEfficiency,doTrans)        //applies correction to raw_data, and overwrites it
131       
132        //if RAW data is ILL type detector, correct raw_data for same counts being written to 4 pixels
133        if(cmpstr(raw_text[9], "ILL   ") == 0 )         //text field in header is 6 characters "ILL---"
134                raw_data /= 4
135        endif
136       
137        //deadtime corrections to raw data
138        deadTime = DetectorDeadtime(raw_text[3],raw_text[9])            //pick the correct detector deadtime
139        itim = raw_ints[2]
140        cntrate = sum(raw_data,-inf,inf)/itim           //080802 use data sum, rather than scaler value
141        dscale = 1/(1-deadTime*cntrate)
142
143#if (exists("ILL_D22")==6)
144        Variable tubeSum
145        // for D22 detector might need to use cntrate/128 as it is the tube response
146        for(ii=0;ii<pixelsX;ii+=1)
147                //sum the counts in each tube
148                tubeSum = 0
149                for(jj=0;jj<pixelsY;jj+=1)
150                        tubeSum += data[jj][ii]
151                endfor
152                // countrate in tube ii
153                cntrate = tubeSum/itim
154                // deadtime scaling in tube ii
155                dscale = 1/(1-deadTime*cntrate)
156                // multiply data[ii][] by the dead time
157                data[][ii] *= dscale
158        endfor
159#endif
160
161        //update totals by adding RAW values to the local ones (write to work header at end of function)
162        total_mon += raw_reals[0]
163#if (exists("ILL_D22")==6)
164        total_det += sum(data,-inf,inf)                 //add the newly scaled detector array
165#else
166        total_det += dscale*raw_reals[2]
167#endif
168        total_trn += raw_reals[39]
169        total_rtime += raw_ints[2]
170        total_numruns +=1
171       
172        //do the beamcenter shifting if there is a mismatch
173        //and then add the two data sets together, changing "data" since it is the workfile data
174        xshift = raw_reals[16] - wrk_beamx
175        yshift = raw_reals[17] - wrk_beamy
176       
177        If((xshift != 0) || (yshift != 0))
178                DoAlert 1,"Do you want to ignore the beam center mismatch?"
179                if(V_flag==1)
180                        xshift=0
181                        yshift=0
182                endif
183        endif
184       
185        If((xshift == 0) && (yshift == 0))              //no shift, just add them
186                data += dscale*raw_data         //do the deadtime correction on RAW here
187        else
188                //shift the beamcenter, then add
189                Make/O/N=1 $(destPath + ":noadd")               //needed to get noadd condition back from ShiftSum()
190                WAVE noadd = $(destPath + ":noadd")
191                Variable sh_sum                 //returned value
192                Print "BEAM CENTER MISMATCH - - BEAM CENTER WILL BE SHIFTED TO THIS FILE'S VALUE"
193                //ii,jj are just indices here, not physical locations - so [0,127] is fine
194                ii=0
195                do
196                        jj=0
197                        do
198                                //get the contribution of shifted data
199                                sh_sum = ShiftSum(data,ii,jj,xshift,yshift,noadd)
200                                if(noadd[0])
201                                        //don't do anything to data[][]
202                                else
203                                        //add the raw_data + shifted sum (and do the deadtime correction on both)
204                                        data[ii][jj] += dscale*(raw_data[ii][jj]+sh_sum)                //do the deadtime correction on RAW here
205                                Endif
206                                jj+=1
207                        while(jj<pixelsY)
208                        ii+=1
209                while(ii<pixelsX)
210        Endif
211       
212        //scale the data to the default montor counts
213        scale = defmon/total_mon
214        data *= scale
215       
216        //all is done, except for the bookkeeping of updating the header info in the work folder
217        textread[1] = date() + " " + time()             //date + time stamp
218        integersread[3] = total_numruns                                         //numruns = more than one
219        realsread[1] = total_mon                        //save the true monitor count
220        realsread[0] = defmon                                   //monitor ct = defmon
221        integersread[2] = total_rtime                   // total counting time
222        realsread[2] = scale*total_det                  //scaled detector counts
223        realsread[39] = scale*total_trn                 //scaled transmission counts
224       
225        //Add the added raw filename to the list of files in the workfile
226        String newfile = ";" + raw_text[0]
227        SVAR oldList = $(destPath + ":fileList")
228        String/G $(destPath + ":fileList") = oldList + newfile
229       
230        //reset the current displaytype to "newtype"
231        String/G root:myGlobals:gDataDisplayType=newType
232       
233        //return to root folder (redundant)
234        SetDataFolder root:
235       
236        Return(0)
237End
238
239//will copy the current contents of the RAW folder to the newType work folder
240//and do the geometric corrections and normalization to monitor counts
241//(the function Add_Raw_to_work(type) adds multiple runs together)
242//
243//the current display type is updated to newType (global)
244//
245Function Raw_to_work(newType)
246        String newType
247       
248        Variable deadTime,defmon,total_mon,total_det,total_trn,total_numruns,total_rtime
249        Variable ii,jj,itim,cntrate,dscale,scale,uscale,wrk_beamx,wrk_beamy
250        String destPath
251       
252// 08/01 detector constants are now returned from a function, based on the detector type and beamline
253//      dt_ornl = 3.4e-6                //deadtime of Ordella detectors as of 30-AUG-99
254//      dt_ill=3.0e-6                   //Cerca detector deadtime constant as of 30-AUG-99
255        defmon=1e8                      //default monitor counts
256       
257        //initialize values before normalization
258        total_mon=0
259        total_det=0
260        total_trn=0
261        total_numruns=0
262        total_rtime=0
263       
264        //Not adding multiple runs, so wipe out the old contents of the work folder and
265        // replace with the contents of raw
266
267        destPath = "root:Packages:NIST:" + newType
268       
269        //check for log-scaling of the RAW data and adjust if necessary
270        ConvertFolderToLinearScale("RAW")
271        //then continue
272       
273        NVAR pixelsX = root:myGlobals:gNPixelsX
274        NVAR pixelsY = root:myGlobals:gNPixelsY
275       
276        //copy from current dir (RAW) to work, defined by destpath
277        DestPath = "root:Packages:NIST:"+newType
278        Duplicate/O $"root:Packages:NIST:RAW:data",$(destPath + ":data")
279//      Duplicate/O $"root:Packages:NIST:RAW:vlegend",$(destPath + ":vlegend")
280        Duplicate/O $"root:Packages:NIST:RAW:textread",$(destPath + ":textread")
281        Duplicate/O $"root:Packages:NIST:RAW:integersread",$(destPath + ":integersread")
282        Duplicate/O $"root:Packages:NIST:RAW:realsread",$(destPath + ":realsread")
283        Variable/G $(destPath + ":gIsLogscale")=0                       //overwite flag in newType folder, data converted (above) to linear scale
284       
285        WAVE data=$(destPath + ":data")                         // these wave references point to the data in work
286        WAVE/T textread=$(destPath + ":textread")                       //that are to be directly operated on
287        WAVE integersread=$(destPath + ":integersread")
288        WAVE realsread=$(destPath + ":realsread")
289        String/G $(destPath + ":fileList") = textread[0]                        //a list of names of the files in the work file (1)
290       
291        //apply nonlinear, Jacobian corrections ---
292        // switches to control what is done, don't do the transmission correction for the BGD measurement
293        NVAR doEfficiency = root:Packages:NIST:gDoDetectorEffCorr
294        NVAR gDoTrans = root:Packages:NIST:gDoTransmissionCorr
295        Variable doTrans = gDoTrans
296        if(cmpstr("BGD",newtype) == 0)
297                doTrans = 0             //skip the trans correction for the BGD file but don't change the value of the global
298        endif
299       
300        DetCorr(data,realsread,doEfficiency,doTrans)            //the parameters are waves, and will be changed by the function
301       
302        //if ILL type detector, correct for same counts being written to 4 pixels
303        if(cmpstr(textread[9], "ILL   ") == 0 )         //text field in header is 6 characters "ILL---"
304                data /= 4
305        endif
306       
307        //deadtime corrections
308        itim = integersread[2]
309        cntrate = sum(data,-inf,inf)/itim               //use sum of detector counts rather than scaler value
310        deadtime = DetectorDeadtime(textread[3],textread[9])    //pick the correct deadtime
311        dscale = 1/(1-deadTime*cntrate)
312       
313#if (exists("ILL_D22")==6)
314        Variable tubeSum
315        // for D22 detector might need to use cntrate/128 as it is the tube response
316        for(ii=0;ii<pixelsX;ii+=1)
317                //sum the counts in each tube
318                tubeSum = 0
319                for(jj=0;jj<pixelsY;jj+=1)
320                        tubeSum += data[jj][ii]
321                endfor
322                // countrate in tube ii
323                cntrate = tubeSum/itim
324                // deadtime scaling in tube ii
325                dscale = 1/(1-deadTime*cntrate)
326                // multiply data[ii][] by the dead time
327                data[][ii] *= dscale
328        endfor
329#endif
330       
331       
332        //update totals to put in the work header (at the end of the function)
333        total_mon += realsread[0]
334#if (exists("ILL_D22")==6)
335        total_det += sum(data,-inf,inf)                 //add the newly scaled detector array
336#else
337        total_det += dscale*realsread[2]
338#endif
339        total_trn += realsread[39]
340        total_rtime += integersread[2]
341        total_numruns +=1
342       
343        // NO xcenter,ycenter shifting is done - this is the first (and only) file in the work folder
344       
345        //only ONE data file- no addition of multiple runs in this function, so data is
346        //just simply corrected for deadtime.
347#ifndef ILL_D22         //correction done tube-by-tube above
348        data *= dscale          //deadtime correction
349#endif
350
351        //scale the data to the default montor counts
352        scale = defmon/total_mon
353        data *= scale
354       
355        //all is done, except for the bookkeeping, updating the header information in the work folder
356        textread[1] = date() + " " + time()             //date + time stamp
357        integersread[3] = total_numruns                                         //numruns = 1
358        realsread[1] = total_mon                        //save the true monitor count
359        realsread[0] = defmon                                   //monitor ct = defmon
360        integersread[2] = total_rtime                   // total counting time
361        realsread[2] = scale*total_det                  //scaled detector counts
362        realsread[39] = scale*total_trn                 //scaled transmission counts
363       
364        //reset the current displaytype to "newtype"
365        String/G root:myGlobals:gDataDisplayType=newType
366       
367        //return to root folder (redundant)
368        SetDataFolder root:
369       
370        Return(0)
371End
372
373//used for adding DRK (beam shutter CLOSED) data to a workfile
374//force the monitor count to 1, since it's irrelevant
375// run data through normal "add" step, then unscale default monitor counts
376//to get the data back on a simple time basis
377//
378Function Raw_to_Work_NoNorm(type)
379        String type
380       
381        WAVE reals=$("root:Packages:NIST:RAW:realsread")
382        reals[1]=1              //true monitor counts, still in raw
383        Raw_to_work(type)
384        //data is now in "type" folder
385        WAVE data=$("root:Packages:NIST:"+type+":data")
386        WAVE new_reals=$("root:Packages:NIST:"+type+":realsread")
387       
388        Variable norm_mon,tot_mon,scale
389       
390        norm_mon = new_reals[0]         //should be 1e8
391        tot_mon = new_reals[1]          //should be 1
392        scale= norm_mon/tot_mon
393       
394        data /= scale           //unscale the data
395       
396        return(0)
397End
398
399//used for adding DRK (beam shutter CLOSED) data to a workfile
400//force the monitor count to 1, since it's irrelevant
401// run data through normal "add" step, then unscale default monitor counts
402//to get the data back on a simple time basis
403//
404Function Add_Raw_to_Work_NoNorm(type)
405        String type
406       
407        WAVE reals=$("root:Packages:NIST:RAW:realsread")
408        reals[1]=1              //true monitor counts, still in raw
409        Add_Raw_to_work(type)
410        //data is now in "type" folder
411        WAVE data=$("root:Packages:NIST:"+type+":data")
412        WAVE new_reals=$("root:Packages:NIST:"+type+":realsread")
413       
414        Variable norm_mon,tot_mon,scale
415       
416        norm_mon = new_reals[0]         //should be 1e8
417        tot_mon = new_reals[1]          //should be equal to the number of runs (1 count per run)
418        scale= norm_mon/tot_mon
419       
420        data /= scale           //unscale the data
421       
422        return(0)
423End
424
425//performs solid angle and non-linear detector corrections to raw data as it is "added" to a work folder
426//function is called by Raw_to_work() and Add_raw_to_work() functions
427//works on the actual data array, assumes that is is already on LINEAR scale
428//
429Function DetCorr(data,realsread,doEfficiency,doTrans)
430        Wave data,realsread
431        Variable doEfficiency,doTrans
432       
433        Variable xcenter,ycenter,x0,y0,sx,sx3,sy,sy3,xx0,yy0
434        Variable ii,jj,dtdist,dtdis2
435        Variable xi,xd,yd,rad,ratio,domega,xy
436        Variable lambda,trans
437       
438//      Print "...doing jacobian and non-linear corrections"
439
440        NVAR pixelsX = root:myGlobals:gNPixelsX
441        NVAR pixelsY = root:myGlobals:gNPixelsY
442       
443        //set up values to send to auxiliary trig functions
444        xcenter = pixelsX/2 + 0.5               // == 64.5 for 128x128 Ordela
445        ycenter = pixelsY/2 + 0.5               // == 64.5 for 128x128 Ordela
446
447        x0 = realsread[16]
448        y0 = realsread[17]
449        sx = realsread[10]
450        sx3 = realsread[11]
451        sy = realsread[13]
452        sy3 = realsread[14]
453       
454        dtdist = 1000*realsread[18]     //sdd in mm
455        dtdis2 = dtdist^2
456       
457        lambda = realsRead[26]
458        trans = RealsRead[4]
459       
460        xx0 = dc_fx(x0,sx,sx3,xcenter)
461        yy0 = dc_fy(y0,sy,sy3,ycenter)
462       
463
464        //waves to contain repeated function calls
465        Make/O/N=(pixelsX) fyy,xx,yy            //Assumes square detector !!!
466        ii=0
467        do
468                xi = ii
469                fyy[ii] = dc_fy(ii+1,sy,sy3,ycenter)
470                xx[ii] = dc_fxn(ii+1,sx,sx3,xcenter)
471                yy[ii] = dc_fym(ii+1,sy,sy3,ycenter)
472                ii+=1
473        while(ii<pixelsX)
474       
475        Make/O/N=(pixelsX,pixelsY) SolidAngle           // testing only
476       
477        ii=0
478        do
479                xi = ii
480                xd = dc_fx(ii+1,sx,sx3,xcenter)-xx0
481                jj=0
482                do
483                        yd = fyy[jj]-yy0
484                        //rad is the distance of pixel ij from the sample
485                        //domega is the ratio of the solid angle of pixel ij versus center pixel
486                        // product xy = 1 for a detector with a linear spatial response (modern Ordela)
487                        // solid angle calculated, dW^3 >=1, so multiply data to raise measured values to correct values.
488                        rad = sqrt(dtdis2 + xd^2 + yd^2)
489                        domega = rad/dtdist
490                        ratio = domega^3
491                        xy = xx[ii]*yy[jj]
492                        data[ii][jj] *= xy*ratio
493                        solidAngle[ii][jj] = xy*ratio           //testing only 
494
495                       
496                        // correction factor for detector efficiency JBG memo det_eff_cor2.doc 3/20/07
497                        // correction inserted 11/2007 SRK
498                        // large angle detector efficiency is >= 1 and will "bump up" the measured value at the highest angles
499                        // so divide here to get the correct answer (5/22/08 SRK)
500                        if(doEfficiency)
501#if (exists("ILL_D22")==6)
502                                data[ii][jj]  /= DetEffCorrILL(lambda,dtdist,xd)                //tube-by-tube corrections
503                  solidAngle[ii][jj] = DetEffCorrILL(lambda,dtdist,xd)
504#else
505                                data[ii][jj] /= DetEffCorr(lambda,dtdist,xd,yd)
506//                              solidAngle[ii][jj] /= DetEffCorr(lambda,dtdist,xd,yd)           //testing only
507#endif
508                        endif
509                       
510                        // large angle transmission calculation is <= 1 and will "bump down" the measured value at the highest angles
511                        // so divide here to get the correct answer
512                        if(doTrans)
513                       
514                                if(trans<0.1 && ii==0 && jj==0)
515                                        Print "***transmission is less than 0.1*** and is a significant correction"
516                                endif
517                               
518                                if(trans==0)
519                                        if(ii==0 && jj==0)
520                                                Print "***transmission is ZERO*** and has been reset to 1.0 for the averaging calculation"
521                                        endif
522                                        trans = 1
523                                endif
524                                       
525                                data[ii][jj] /= LargeAngleTransmissionCorr(trans,dtdist,xd,yd)          //moved from 1D avg SRK 11/2007
526                                //solidAngle[ii][jj] = LargeAngleTransmissionCorr(trans,dtdist,xd,yd)           //testing only
527                        endif
528                       
529                        jj+=1
530                while(jj<pixelsX)
531                ii+=1
532        while(ii<pixelsX)
533       
534        //clean up waves
535//      Killwaves/Z fyy,xx,yy
536       
537        Return(0)
538End
539
540//trig function used by DetCorr()
541Function dc_fx(x,sx,sx3,xcenter)
542        Variable x,sx,sx3,xcenter
543       
544        Variable result
545       
546        result = sx3*tan((x-xcenter)*sx/sx3)
547        Return(result)
548End
549
550//trig function used by DetCorr()
551Function dc_fy(y,sy,sy3,ycenter)
552        Variable y,sy,sy3,ycenter
553       
554        Variable result
555       
556        result = sy3*tan((y-ycenter)*sy/sy3)
557        Return(result)
558End
559
560//trig function used by DetCorr()
561Function dc_fxn(x,sx,sx3,xcenter)
562        Variable x,sx,sx3,xcenter
563       
564        Variable result
565       
566        result = (cos((x-xcenter)*sx/sx3))^2
567        Return(result)
568End
569
570//trig function used by DetCorr()
571Function dc_fym(y,sy,sy3,ycenter)
572        Variable y,sy,sy3,ycenter
573       
574        Variable result
575       
576        result = (cos((y-ycenter)*sy/sy3))^2
577        Return(result)
578End
579
580//distances passed in are in mm
581// dtdist is SDD
582// xd and yd are distances from the beam center to the current pixel
583//
584Function DetEffCorr(lambda,dtdist,xd,yd)
585        Variable lambda,dtdist,xd,yd
586       
587        Variable theta,cosT,ff,stAl,stHe
588       
589        theta = atan( (sqrt(xd^2 + yd^2))/dtdist )
590        cosT = cos(theta)
591       
592        stAl = 0.00967*lambda*0.8               //dimensionless, constants from JGB memo
593        stHe = 0.146*lambda*2.5
594       
595        ff = exp(-stAl/cosT)*(1-exp(-stHe/cosT)) / ( exp(-stAl)*(1-exp(-stHe)) )
596               
597        return(ff)
598End
599
600// DIVIDE the intensity by this correction to get the right answer
601Function LargeAngleTransmissionCorr(trans,dtdist,xd,yd)
602        Variable trans,dtdist,xd,yd
603
604        //angle dependent transmission correction
605        Variable uval,arg,cos_th,correction,theta
606       
607        ////this section is the trans_correct() VAX routine
608//      if(trans<0.1)
609//              Print "***transmission is less than 0.1*** and is a significant correction"
610//      endif
611//      if(trans==0)
612//              Print "***transmission is ZERO*** and has been reset to 1.0 for the averaging calculation"
613//              trans = 1
614//      endif
615       
616        theta = atan( (sqrt(xd^2 + yd^2))/dtdist )              //theta at the input pixel
617       
618        //optical thickness
619        uval = -ln(trans)               //use natural logarithm
620
621//      theta = 2*asin(lambda*qval/(4*pi))
622
623        cos_th = cos(theta)
624        arg = (1-cos_th)/cos_th
625        if((uval<0.01) || (cos_th>0.99))                //OR
626                //small arg, approx correction
627                correction= 1-0.5*uval*arg
628        else
629                //large arg, exact correction
630                correction = (1-exp(-uval*arg))/(uval*arg)
631        endif
632
633        //end of transmission/pathlength correction
634
635        return(correction)
636end
637
638//******************
639//direct port of the FORTRAN code for calculating the weighted
640//shifted element to add when beam centers in data headers do not match
641//(indices updated to [0,n-1] indexing rather than (1,n) of fortran
642//
643// as of IGOR 4.0, could be rewritten to pass-by-reference noadd, rather than wave, but the function
644// is so little used, it's not worth the time
645Function ShiftSum(DATA,ip,jp,XSHIFT,YSHIFT,noadd)
646        Wave data
647        Variable ip,jp,xshift,yshift
648        Wave noadd
649//
650//       COMPUTE WEIGHTED OFFSET ELEMENT SUM FOR USE IN SANS DATA
651//       ANALYSIS MODULES.
652//
653// "data" wave passed in is the current contents of the work file
654// sum_val is the return value of the function
655// "noadd" is passed back to the calling function as a one-point wave
656
657        Variable XDELTA,YDELTA,kk,II,JJ,ISHIFT,JSHIFT,sum_val
658        Make/O/N=4 iii,jjj,a
659
660//       -----------------------------------------------------------------
661
662        ISHIFT = trunc(XSHIFT)          // INTEGER PART, trunc gives int closest in dierction of zero
663        XDELTA = XSHIFT - ISHIFT        //FRACTIONAL PART.
664        JSHIFT = trunc(YSHIFT)
665        YDELTA = YSHIFT - JSHIFT
666        II = ip + ISHIFT
667        JJ = jp + JSHIFT
668
669//       SHIFT IS DEFINED AS A VECTOR ANCHORED AT THE STATIONARY CENTER
670//       AND POINTING TO THE MOVABLE CENTER.  THE MOVABLE FIELD IS THUS
671//       ACTUALLY MOVED BY -SHIFT.
672//
673        IF ((XDELTA>= 0) && (YDELTA >= 0))              // CASE I ---- "%&" is "and"
674                III[0] = II
675                JJJ[0] = JJ
676                III[1] = II + 1
677                JJJ[1] = JJ
678                III[2] = II + 1
679                JJJ[2] = JJ + 1
680                III[3] = II
681                JJJ[3] = JJ + 1
682                A[0] = (1. - XDELTA)*(1. - YDELTA)
683                A[1] = XDELTA*(1. - YDELTA)
684                A[2] = XDELTA*YDELTA
685                A[3] = (1. - XDELTA)*YDELTA
686        Endif
687        IF ((XDELTA >= 0) && (YDELTA < 0))              // CASE II.
688                III[0] = II
689                JJJ[0] = JJ
690                III[1] = II
691                JJJ[1] = JJ - 1
692                III[2] = II + 1
693                JJJ[2] = JJ - 1
694                III[3] = II + 1
695                JJJ[3] = JJ
696                A[0] = (1. - XDELTA)*(1. + YDELTA)
697                A[1] = (1. - XDELTA)*(-YDELTA)
698                A[2] = XDELTA*(-YDELTA)
699                A[3] = XDELTA*(1. + YDELTA)
700        Endif
701        IF ((XDELTA < 0) && (YDELTA >= 0))              // CASE III.
702                III[0] = II
703                JJJ[0] = JJ
704                III[1] = II
705                JJJ[1] = JJ + 1
706                III[2] = II - 1
707                JJJ[2] = JJ + 1
708                III[3] = II - 1
709                JJJ[3] = JJ
710                A[0] = (1. + XDELTA)*(1 - YDELTA)
711                A[1] = (1. + XDELTA)*YDELTA
712                A[2] = -XDELTA*YDELTA
713                A[3] = -XDELTA*(1. - YDELTA)
714        Endif
715        IF ((XDELTA < 0) && (YDELTA < 0))               //CASE IV.
716                III[0] = II
717                JJJ[0] = JJ
718                III[1] = II - 1
719                JJJ[1] = JJ
720                III[2] = II - 1
721                JJJ[2] = JJ - 1
722                III[3] = II
723                JJJ[3] = JJ - 1
724                A[0] = (1. + XDELTA)*(1. + YDELTA)
725                A[1] = -XDELTA*(1. + YDELTA)
726                A[2] = (-XDELTA)*(-YDELTA)
727                A[3] = (1. + XDELTA)*(-YDELTA)
728        Endif
729
730        NVAR pixelsX = root:myGlobals:gNPixelsX
731        NVAR pixelsY = root:myGlobals:gNPixelsY
732//check to see if iii[0],jjj[0] are valid detector elements, in [0,127]
733//if not set noadd[0] to 1, to let calling routine know NOT to add
734//        CALL TESTIJ(III(1),JJJ(1),OKIJ)
735        NOADD[0] = 0
736        if( (iii[0]<0) || (iii[0]>(pixelsX-1)) )
737                noadd[0] = 1
738        endif
739        if((jjj[0]<0) || (jjj[0]>(pixelsY-1)) )
740                noadd[0] = 1
741        endif
742       
743
744       
745        sum_val = 0.
746        kk = 0
747        Do
748                IF(JJJ[kk] == pixelsX)
749                        //do nothing
750                else
751                        sum_val += A[kk]*DATA[III[kk]][JJJ[kk]]
752                endif
753                kk+=1
754        while(kk<4)
755       
756        //clean up waves
757        KillWaves/z iii,jjj,a
758       
759        RETURN (sum_val)
760       
761End             //function ShiftSum
762
763//************************
764//unused testing procedure, may not be up-to-date with other procedures
765//check before re-implementing
766//
767Proc DIV_a_Workfile(type)
768        String type
769        Prompt type,"WORK data type",popup,"COR;SAM;EMP;BGD"
770       
771        //macro will take whatever is in SELECTED folder and DIVide it by the current
772        //contents of the DIV folder - the function will check for existence
773        //before proceeding
774       
775        Variable err
776        err = Divide_work(type)         //returns err = 1 if data doesn't exist in specified folders
777       
778        if(err)
779                Abort "error in Divide_work"
780        endif
781       
782        //contents are always dumped to CAL
783        type = "CAL"
784       
785        String newTitle = "WORK_"+type
786        DoWindow/F SANS_Data
787        DoWindow/T SANS_Data, newTitle
788        KillStrings/Z newTitle
789       
790        //need to update the display with "data" from the correct dataFolder
791        //reset the current displaytype to "type"
792        String/G root:myGlobals:gDataDisplayType=Type
793       
794        fRawWindowHook()
795       
796End
797
798//function will divide the contents of "type" folder with the contents of
799//the DIV folder
800// all data is converted to linear scale for the calculation
801//
802Function Divide_work(type)
803        String type
804       
805        //check for existence of data in type and DIV
806        // if the desired workfile doesn't exist, let the user know, and abort
807        String destPath=""
808        destPath = "root:Packages:NIST:"+Type + ":data"
809        if(WaveExists($destpath) == 0)
810                Print "There is no work file in "+type+"--Aborting"
811                Return(1)               //error condition
812        Endif
813        //check for DIV
814        // if the DIV workfile doesn't exist, let the user know,and abort
815        destPath = "root:Packages:NIST:DIV:data"
816        if(WaveExists($destpath) == 0)
817                Print "There is no work file in DIV --Aborting"
818                Return(1)               //error condition
819        Endif
820        //files exist, proceed
821       
822        //check for log-scaling of the "DIV" data and adjust if necessary
823        ConvertFolderToLinearScale("DIV")
824       
825        //copy type information to CAL, wiping out the old contents of the CAL folder first
826       
827        //destPath = "root:Packages:NIST:CAL"
828        //SetDataFolder destPath
829        //KillWaves/A/Z                 //get rid of the old data in CAL folder
830
831        //check for log-scaling of the "type" data and adjust if necessary
832        ConvertFolderToLinearScale(type)
833        //then continue
834
835        //copy from current dir (type)=destPath to CAL, overwriting CAL contents
836        destPath = "root:Packages:NIST:" + type
837        Duplicate/O $(destPath + ":data"),$"root:Packages:NIST:CAL:data"
838//      Duplicate/O $(destPath + ":vlegend"),$"root:Packages:NIST:CAL:vlegend"
839        Duplicate/O $(destPath + ":textread"),$"root:Packages:NIST:CAL:textread"
840        Duplicate/O $(destPath + ":integersread"),$"root:Packages:NIST:CAL:integersread"
841        Duplicate/O $(destPath + ":realsread"),$"root:Packages:NIST:CAL:realsread"
842        //need to save a copy of filelist string too (from the current type folder)
843        SVAR oldFileList = $(destPath + ":fileList")
844
845        //now switch to reference waves in CAL folder
846        destPath = "root:Packages:NIST:CAL"
847        //make appropriate wave references
848        Wave data=$(destPath + ":data")                                 // these wave references point to the data in CAL
849        Wave/t textread=$(destPath + ":textread")                       //that are to be directly operated on
850        Wave integersread=$(destPath + ":integersread")
851        Wave realsread=$(destPath + ":realsread")
852        Variable/G $(destPath + ":gIsLogScale")=0                       //make new flag in CAL folder, data is linear scale
853        //need to copy filelist string too
854        String/G $(destPath + ":fileList") = oldFileList
855
856        Wave div_data = $"root:Packages:NIST:DIV:data"          //hard-wired in....
857        //do the division, changing data in CAL
858        data /= div_data
859       
860        //update CAL header
861        textread[1] = date() + " " + time()             //date + time stamp
862       
863        Return(0)
864End
865
866//test procedure, not called anymore
867Proc AbsoluteScaling(type,c0,c1,c2,c3,c4,c5)
868        String type
869        Variable c0=1,c1=0.1,c2=0.95,c3=0.1,c4=1,c5=32.0
870        Prompt type,"WORK data type",popup,"CAL;COR;SAM"
871        Prompt c0, "Sample Transmission"
872        Prompt c1, "Sample Thickness (cm)"
873        Prompt c2, "Standard Transmission"
874        Prompt c3, "Standard Thickness (cm)"
875        Prompt c4, "I(0) from standard fit (normalized to 1E8 monitor cts)"
876        Prompt c5, "Standard Cross-Section (cm-1)"
877
878        Variable err
879        //call the function to do the math
880        //data from "type" will be scaled and deposited in ABS
881        err = Absolute_Scale(type,c0,c1,c2,c3,c4,c5)
882       
883        if(err)
884                Abort "Error in Absolute_Scale()"
885        endif
886       
887        //contents are always dumped to ABS
888        type = "ABS"
889       
890        String newTitle = "WORK_"+type
891        DoWindow/F SANS_Data
892        DoWindow/T SANS_Data, newTitle
893        KillStrings/Z newTitle
894       
895        //need to update the display with "data" from the correct dataFolder
896        //reset the current displaytype to "type"
897        String/G root:myGlobals:gDataDisplayType=Type
898       
899        fRawWindowHook()
900       
901End
902
903//s_ is the standard
904//w_ is the "work" file
905//both are work files and should already be normalized to 10^8 monitor counts
906Function Absolute_Scale(type,w_trans,w_thick,s_trans,s_thick,s_izero,s_cross)
907        String type
908        Variable w_trans,w_thick,s_trans,s_thick,s_izero,s_cross
909       
910        //convert the "type" data to absolute scale using the given standard information
911        //copying the "type" waves to ABS
912       
913        //check for existence of data, rescale to linear if needed
914        String destPath
915        //check for "type"
916        destPath = "root:Packages:NIST:"+Type + ":data"
917        if(WaveExists($destpath) == 0)
918                Print "There is no work file in "+type+"--Aborting"
919                Return(1)               //error condition
920        Endif
921        //check for log-scaling of the "type" data and adjust if necessary
922        destPath = "root:Packages:NIST:"+Type
923        NVAR gIsLogScale = $(destPath + ":gIsLogScale")
924        if(gIsLogScale)
925                Duplicate/O $(destPath + ":linear_data") $(destPath + ":data")//back to linear scale
926                Variable/G $(destPath + ":gIsLogScale")=0       //the "type" data is not logscale anymore
927        endif
928       
929        //copy "oldtype" information to ABS
930        //overwriting out the old contents of the ABS folder (/O option in Duplicate)
931        //copy over the waves data,vlegend,text,integers,reals(read)
932
933        String oldType= "root:Packages:NIST:"+type              //this is where the data to be absoluted is
934        //copy from current dir (type) to ABS, defined by destPath
935        Duplicate/O $(oldType + ":data"),$"root:Packages:NIST:ABS:data"
936//      Duplicate/O $(oldType + ":vlegend"),$"root:Packages:NIST:ABS:vlegend"
937        Duplicate/O $(oldType + ":textread"),$"root:Packages:NIST:ABS:textread"
938        Duplicate/O $(oldType + ":integersread"),$"root:Packages:NIST:ABS:integersread"
939        Duplicate/O $(oldType + ":realsread"),$"root:Packages:NIST:ABS:realsread"
940        //need to save a copy of filelist string too (from the current type folder)
941        SVAR oldFileList = $(oldType + ":fileList")
942        //need to copy filelist string too
943        String/G $"root:Packages:NIST:ABS:fileList" = oldFileList
944       
945        //now switch to ABS folder
946        //make appropriate wave references
947        WAVE data=$"root:Packages:NIST:ABS:data"                                        // these wave references point to the "type" data in ABS
948        WAVE/T textread=$"root:Packages:NIST:ABS:textread"                      //that are to be directly operated on
949        WAVE integersread=$"root:Packages:NIST:ABS:integersread"
950        WAVE realsread=$"root:Packages:NIST:ABS:realsread"
951        Variable/G $"root:Packages:NIST:ABS:gIsLogscale"=0                      //make new flag in ABS folder, data is linear scale
952       
953        //do the actual absolute scaling here, modifying the data in ABS
954        Variable defmon = 1e8,w_moncount,s1,s2,s3,s4
955       
956        w_moncount = realsread[0]               //monitor count in "type"
957        if(w_moncount == 0)
958                //zero monitor counts will give divide by zero ---
959                DoAlert 0,"Total monitor count in data file is zero. No rescaling of data"
960                Return(1)               //report error
961        Endif
962       
963        //calculate scale factor
964        s1 = defmon/realsread[0]                //[0] is monitor count (s1 should be 1)
965        s2 = s_thick/w_thick
966        s3 = s_trans/w_trans
967        s4 = s_cross/s_izero
968       
969        data *= s1*s2*s3*s4
970       
971        //********* 15APR02
972        // DO NOt correct for atenuators here - the COR step already does this, putting all of the data one equal
973        // footing (zero atten) before doing the subtraction.
974        //
975        //Print "ABS data multiplied by  ",s1*s2*s3*s4/attenFactor
976       
977        //update the ABS header information
978        textread[1] = date() + " " + time()             //date + time stamp
979       
980        Return (0) //no error
981End
982
983//*************
984// start of section of functions used for workfile math panel
985//*************
986
987
988//function will copy the contents of oldtype folder to newtype folder
989//converted to linear scale before copying
990//******data in newtype is overwritten********
991//
992Function CopyWorkContents(oldtype,newtype)
993        String oldtype,newtype
994       
995        //check for existence of data in oldtype
996        // if the desired workfile doesn't exist, let the user know, and abort
997        String destPath=""
998        destPath = "root:Packages:NIST:"+oldType + ":data"
999        if(WaveExists($destpath) == 0)
1000                Print "There is no work file in "+oldtype+"--Aborting"
1001                Return(1)               //error condition
1002        Endif
1003       
1004        //check for log-scaling of the "type" data and adjust if necessary
1005        ConvertFolderToLinearScale(oldtype)
1006        Fix_LogLinButtonState(0)                //make sure the button reflects the new linear scaling
1007        //then continue
1008
1009        //copy from current dir (type)=destPath to newtype, overwriting newtype contents
1010        destPath = "root:Packages:NIST:" + oldtype
1011        Duplicate/O $(destPath + ":data"),$("root:Packages:NIST:"+newtype+":data")
1012        Duplicate/O $(destPath + ":textread"),$("root:Packages:NIST:"+newtype+":textread")
1013        Duplicate/O $(destPath + ":integersread"),$("root:Packages:NIST:"+newtype+":integersread")
1014        Duplicate/O $(destPath + ":realsread"),$("root:Packages:NIST:"+newtype+":realsread")
1015        //
1016        // be sure to get rid of the linear_data if it exists in the destination folder
1017        KillWaves/Z $("root:Packages:NIST:"+newtype+":linear_data")
1018        //need to save a copy of filelist string too (from the current type folder)
1019        SVAR oldFileList = $(destPath + ":fileList")
1020
1021        //now switch to reference waves in newtype folder
1022        destPath = "root:Packages:NIST:"+newtype
1023        Variable/G $(destPath + ":gIsLogScale")=0                       //make new flag in newtype folder, data is linear scale
1024        //need to copy filelist string too
1025        String/G $(destPath + ":fileList") = oldFileList
1026
1027        Return(0)
1028End
1029
1030//Entry procedure from main panel
1031//
1032Proc CopyWorkFolder(oldType,newType)
1033        String oldType,newType
1034        Prompt oldType,"Source WORK data type",popup,"SAM;EMP;BGD;DIV;COR;CAL;RAW;ABS;STO;SUB;DRK;"
1035        Prompt newType,"Destination WORK data type",popup,"SAM;EMP;BGD;DIV;COR;CAL;RAW;ABS;STO;SUB;DRK;"
1036//      Prompt oldType,"Source WORK data type",popup,"AAA;BBB;CCC;DDD;EEE;FFF;GGG;"
1037//      Prompt newType,"Destination WORK data type",popup,"AAA;BBB;CCC;DDD;EEE;FFF;GGG;"
1038
1039        // data folder "old" will be copied to "new" (and will overwrite)
1040        CopyWorkContents(oldtype,newtype)
1041End
1042
1043//initializes datafolder and constants necessary for the workfilemath panel
1044//
1045Proc Init_WorkMath()
1046        //create the data folder
1047        //String str = "AAA;BBB;CCC;DDD;EEE;FFF;GGG;"
1048        String str = "File_1;File_2;Result;"
1049        NewDataFolder/O/S root:Packages:NIST:WorkMath
1050        String/G gFolderList=str
1051        Variable ii=0,num=itemsinlist(str)
1052        do
1053                Execute "NewDataFolder/O "+StringFromList(ii, str ,";")
1054                ii+=1
1055        while(ii<num)
1056        Variable/G const1=1,const2=1
1057       
1058        SetDataFolder root:
1059End
1060
1061//entry procedure to invoke the workfilemath panel, initializes if needed
1062//
1063Proc Show_WorkMath_Panel()
1064        DoWindow/F WorkFileMath
1065        if(V_flag==0)
1066                Init_WorkMath()
1067                WorkFileMath()
1068        Endif
1069End
1070
1071//attempts to perform the selected math operation based on the selections in the panel
1072// aborts with an error condition if operation can't be completed
1073// or puts the final answer in the Result folder, and displays the selected data
1074//
1075Function WorkMath_DoIt_ButtonProc(ctrlName) : ButtonControl
1076        String ctrlName
1077
1078        String str1,str2,oper,dest = "Result"
1079        String pathStr,workMathStr="WorkMath:"
1080       
1081        //get the panel selections (these are the names of the files on disk)
1082        PathInfo catPathName
1083        pathStr=S_Path
1084        ControlInfo popup0
1085        str1=S_Value
1086        ControlInfo popup1
1087        str2=S_Value
1088        ControlInfo popup2
1089        oper=S_Value
1090       
1091        //check that something has been selected for operation and destination
1092        if(cmpstr(oper,"Operation")==0)
1093                Abort "Select a math operand from the popup"
1094        Endif
1095
1096        //constants from globals
1097        NVAR const1=root:Packages:NIST:WorkMath:const1
1098        NVAR const2=root:Packages:NIST:WorkMath:const2
1099        Printf "(%g)%s %s (%g)%s = %s\r", const1,str1,oper,const2,str2,dest
1100        //check for proper folders (all 3 must be different)
1101       
1102        //load the data in here...
1103        //set #1
1104        Load_NamedASC_File(pathStr+str1,workMathStr+"File_1")
1105       
1106        NVAR pixelsX = root:myGlobals:gNPixelsX         //OK, location is correct
1107        NVAR pixelsY = root:myGlobals:gNPixelsY
1108       
1109        WAVE/Z data1=$("root:Packages:NIST:"+workMathStr+"File_1:data")
1110        If(cmpstr(str2,"UNIT MATRIX")==0)
1111                Make/O/N=(pixelsX,pixelsY) root:Packages:NIST:WorkMath:data             //don't put in File_2 folder
1112                Wave/Z data2 =  root:Packages:NIST:WorkMath:data                        //it's not real data!
1113                data2=1
1114        else
1115                //Load set #2
1116                Load_NamedASC_File(pathStr+str2,workMathStr+"File_2")
1117                WAVE/Z data2=$("root:Packages:NIST:"+workMathStr+"File_2:data")
1118        Endif
1119
1120        ///////
1121       
1122        //now that we know that data exists, convert each of the operands to linear scale
1123        ConvertFolderToLinearScale(workMathStr+"File_1")
1124        If(cmpstr(str2,"UNIT MATRIX")!=0)
1125                ConvertFolderToLinearScale(workMathStr+"File_2")                //don't need to convert unit matrix to linear
1126        endif
1127        //copy contents of str1 folder to dest and create the wave ref (it will exist)
1128        CopyWorkContents(workMathStr+"File_1",workMathStr+dest)
1129        WAVE/Z destData=$("root:Packages:NIST:"+workMathStr+dest+":data")
1130       
1131        //dispatch
1132        strswitch(oper)
1133                case "*":               //multiplication
1134                        destData = const1*data1 * const2*data2
1135                        break   
1136                case "_":               //subtraction
1137                        destData = const1*data1 - const2*data2
1138                        break
1139                case "/":               //division
1140                        destData = (const1*data1) / (const2*data2)
1141                        break
1142                case "+":               //addition
1143                        destData = const1*data1 + const2*data2
1144                        break                   
1145        endswitch
1146       
1147        //show the result
1148        WorkMath_Display_PopMenuProc("",0,"Result")
1149End
1150
1151// closes the panel and kills the data folder when done
1152//
1153Function WorkMath_Done_ButtonProc(ctrlName) : ButtonControl
1154        String ctrlName
1155       
1156        DoAlert 1,"Closing the panel will kill all of the data you have loaded into memory. Do you want to continue?"
1157        If(V_Flag==2)
1158                return(0)               //don't do anything
1159        Endif
1160        //kill the panel
1161        DoWindow/K WorkFileMath
1162        //wipe out the data folder of globals
1163        SVAR dataType=root:myGlobals:gDataDisplayType
1164        if(strsearch(dataType, "WorkMath", 0 ) != -1)           //kill the SANS_Data graph if needed
1165                DoWindow/K SANS_Data
1166        Endif
1167        KillDataFolder root:Packages:NIST:WorkMath
1168End
1169
1170// loads data into the specified folder
1171//
1172// currently unused since button has been removed from panel
1173//
1174Function WorkMath_Load_ButtonProc(ctrlName) : ButtonControl
1175        String ctrlName
1176       
1177        String destStr=""
1178        SVAR folderList=root:Packages:NIST:WorkMath:gFolderList
1179        Prompt destStr,"Select the destination folder",popup,folderList
1180        DoPrompt "Folder for ASC Load",destStr
1181       
1182        if(V_flag==1)
1183                return(1)               //user abort, do nothing
1184        Endif
1185       
1186        String destFolder = "WorkMath:"+destStr
1187       
1188        Load_ASC_File("Pick the ASC file",destFolder)
1189End
1190
1191// changes the display of the SANS_Data window based on popped data type
1192// first loads in the data from the File1 or File2 popup as needed
1193// then displays the selcted dataset, if it exists
1194// makes use of procedure from DisplayUtils
1195//
1196// - Always replaces File1 or File2 with fresh data from disk
1197//
1198Function WorkMath_Display_PopMenuProc(ctrlName,popNum,popStr) : PopupMenuControl
1199        String ctrlName
1200        Variable popNum
1201        String popStr
1202       
1203        String folder="WorkMath:",pathStr,str1
1204
1205        PathInfo catPathName
1206        pathStr=S_Path
1207       
1208        //if display result, just do it and return
1209        if(cmpstr(popStr,"Result")==0)
1210                Execute "ChangeDisplay(\""+folder+popstr+"\")"
1211                return(0)
1212        endif
1213        // if file1 or file2, load in the data and display
1214        if(cmpstr(popStr,"File_1")==0)
1215                ControlInfo popup0
1216                str1 = S_Value
1217        Endif
1218        if(cmpstr(popStr,"File_2")==0)
1219                ControlInfo popup1
1220                str1 = S_Value
1221        Endif
1222        //don't load or display the unit matrix
1223        Print str1
1224        if(cmpstr(str1,"UNIT MATRIX")!=0)
1225                Load_NamedASC_File(pathStr+str1,folder+popStr)
1226                //change the display
1227                Execute "ChangeDisplay(\""+folder+popstr+"\")"
1228        endif
1229        return(0)       
1230End
1231
1232//simple panel to do workfile arithmetic
1233//
1234Proc WorkFileMath()
1235        PauseUpdate; Silent 1           // building window...
1236        NewPanel /W=(610,211,880,490)/K=2 as "Work File Math"           // replace /K=2 flag
1237        DoWindow/C WorkFileMath
1238        ModifyPanel cbRGB=(47802,54484,6682)
1239        ModifyPanel fixedSize=1
1240        SetDrawLayer UserBack
1241        DrawLine 6,166,214,166
1242        SetDrawEnv fstyle= 4
1243        DrawText 10,34,"File #1:"
1244        SetDrawEnv fstyle= 4
1245        DrawText 13,129,"File #2:"
1246        DrawText 78,186,"= Result"
1247        Button button0,pos={28,245},size={50,20},proc=WorkMath_DoIt_ButtonProc,title="Do It"
1248        Button button0,help={"Performs the specified arithmetic"}
1249        Button button1,pos={183,245},size={50,20},proc=WorkMath_Done_ButtonProc,title="Done"
1250        Button button1,help={"Closes the panel"}
1251//      Button button2,pos={30,8},size={110,20},proc=WorkMath_Load_ButtonProc,title="Load ASC Data"
1252//      Button button2,help={"Loads ASC data files into the specified folder"}
1253        Button button3,pos={205,8},size={25,20},proc=ShowWorkMathHelp,title="?"
1254        Button button3,help={"Show help file for math operations on 2-D data sets"}
1255        SetVariable setvar0,pos={9,46},size={70,15},title=" "
1256        SetVariable setvar0,limits={-Inf,Inf,0},value= root:Packages:NIST:WorkMath:const1
1257        SetVariable setvar0,help={"Multiplicative constant for the first dataset"}
1258        PopupMenu popup0,pos={89,44},size={84,20},title="X  "
1259        PopupMenu popup0,mode=1,popvalue="1st Set",value= ASC_FileList()
1260        PopupMenu popup0,help={"Selects the first dataset for the operation"}
1261        PopupMenu popup1,pos={93,136},size={89,20},title="X  "
1262        PopupMenu popup1,mode=1,popvalue="2nd Set",value= "UNIT MATRIX;"+ASC_FileList()
1263        PopupMenu popup1,help={"Selects the second dataset for the operation"}
1264        PopupMenu popup2,pos={50,82},size={70,20},title="Operator  "
1265        PopupMenu popup2,mode=3,popvalue="Operation",value= #"\"+;_;*;/;\""
1266        PopupMenu popup2,help={"Selects the mathematical operator"}
1267        SetVariable setvar1,pos={13,139},size={70,15},title=" "
1268        SetVariable setvar1,limits={-Inf,Inf,0},value= root:Packages:NIST:WorkMath:const2
1269        SetVariable setvar1,help={"Multiplicative constant for the second dataset"}
1270//      PopupMenu popup3,pos={27,167},size={124,20},title=" = Destination"
1271//      PopupMenu popup3,mode=1,popvalue="Destination",value= root:Packages:NIST:WorkMath:gFolderList
1272//      PopupMenu popup3,help={"Selects the destination folder"}
1273        PopupMenu popup4,pos={55,204},size={103,20},proc=WorkMath_Display_PopMenuProc,title="Display"
1274        PopupMenu popup4,mode=3,value= "File_1;File_2;Result;"
1275        PopupMenu popup4,help={"Displays the data in the specified folder"}
1276EndMacro
1277
1278//jump to the help topic
1279Function ShowWorkMathHelp(ctrlName) : ButtonControl
1280        String ctrlName
1281        DisplayHelpTopic/Z/K=1 "SANS Data Reduction Tutorial[2-D Work File Arithmetic]"
1282        if(V_flag !=0)
1283                DoAlert 0,"The SANS Data Reduction Tutorial Help file could not be found"
1284        endif
1285End
1286
1287//utility function to clear the contents of a data folder
1288//won't clear data that is in use -
1289//
1290Function ClearDataFolder(type)
1291        String type
1292       
1293        SetDataFolder $("root:Packages:NIST:"+type)
1294        KillWaves/a/z
1295        KillStrings/a/z
1296        KillVariables/a/z
1297        SetDataFolder root:
1298End
1299
1300
1301
1302//fileStr must be the FULL path and filename on disk
1303//destFolder is the path to the Igor folder where the data is to be deposited
1304// - "Packages:NIST:WorkMath:File_1" for example, compatible with SANS_Data display type
1305//
1306Function Load_NamedASC_File(fileStr,destFolder)
1307        String fileStr,destFolder
1308
1309        Variable refnum
1310       
1311        //read in the data
1312        ReadASCData(fileStr,destFolder)
1313
1314        //the calling macro must change the display type
1315        String/G root:myGlobals:gDataDisplayType=destFolder
1316       
1317        FillFakeHeader_ASC(destFolder)          //uses info on the panel, if available
1318
1319        //data is displayed here, and needs header info
1320       
1321        fRawWindowHook()
1322       
1323        return(0)
1324End
1325
1326
1327//function called by the main entry procedure (the load button)
1328//loads data into the specified folder, and wipes out what was there
1329//
1330//aborts if no file was selected
1331//
1332// reads the data in if all is OK
1333//
1334// currently unused, as load button has been replaced
1335//
1336Function Load_ASC_File(msgStr,destFolder)
1337        String msgStr,destFolder
1338
1339        String filename="",pathStr=""
1340        Variable refnum
1341
1342        //check for the path
1343        PathInfo catPathName
1344        If(V_Flag==1)           //      /D does not open the file
1345                Open/D/R/T="????"/M=(msgStr)/P=catPathName refNum
1346        else
1347                Open/D/R/T="????"/M=(msgStr) refNum
1348        endif
1349        filename = S_FileName           //get the filename, or null if canceled from dialog
1350        if(strlen(filename)==0)
1351                //user cancelled, abort
1352                SetDataFolder root:
1353                Abort "No file selected, action aborted"
1354        Endif
1355       
1356        //read in the data
1357        ReadASCData(filename,destFolder)
1358
1359        //the calling macro must change the display type
1360        String/G root:myGlobals:gDataDisplayType=destFolder
1361       
1362        FillFakeHeader_ASC(destFolder)          //uses info on the panel, if available
1363
1364        //data is displayed here, and needs header info
1365       
1366        fRawWindowHook()
1367       
1368        return(0)
1369End
1370
1371
1372
1373//function called by the popups to get a file list of data that can be sorted
1374// this procedure simply removes the raw data files from the string - there
1375//can be lots of other junk present, but this is very fast...
1376//
1377Function/S ASC_FileList()
1378
1379        String list="",newList="",item=""
1380        Variable num,ii
1381       
1382        //check for the path
1383        PathInfo catPathName
1384        if(V_Flag==0)
1385                DoAlert 0, "Data path does not exist - pick the data path from the button on the main panel"
1386                Return("")
1387        Endif
1388       
1389        list = IndexedFile(catpathName,-1,"????")
1390       
1391        list = RemoveFromList(ListMatch(list,"*.SA1*",";"), list, ";", 0)
1392        list = RemoveFromList(ListMatch(list,"*.SA2*",";"), list, ";", 0)
1393        list = RemoveFromList(ListMatch(list,"*.SA3*",";"), list, ";", 0)
1394        list = RemoveFromList(ListMatch(list,".*",";"), list, ";", 0)
1395        list = RemoveFromList(ListMatch(list,"*.pxp",";"), list, ";", 0)
1396        list = RemoveFromList(ListMatch(list,"*.DIV",";"), list, ";", 0)
1397        list = RemoveFromList(ListMatch(list,"*.GSP",";"), list, ";", 0)
1398        list = RemoveFromList(ListMatch(list,"*.MASK",";"), list, ";", 0)
1399
1400        //remove VAX version numbers
1401        list = RemoveVersNumsFromList(List)
1402        //sort
1403        newList = SortList(List,";",0)
1404
1405        return newlist
1406End
Note: See TracBrowser for help on using the repository browser.