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

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

Changing ILL_ files to use the #define ILL_D22, removing the need for Lionel's verison of WorkFileUtils?. The change there was in the DetCorr? function, doing a tuby-by-tube correction rather than our array correction. We can make use of this later for vSANS, surely.

File size: 44.1 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:myGlobals:gDoDetectorEffCorr
124        NVAR gDoTrans = root:myGlobals: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#ifdef ILL_D22
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#ifdef ILL_D22
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:myGlobals:gDoDetectorEffCorr
294        NVAR gDoTrans = root:myGlobals: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#ifdef ILL_D22
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#ifdef ILL_D22 
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                        rad = sqrt(dtdis2 + xd^2 + yd^2)
487                        domega = rad/dtdist
488                        ratio = domega^3
489//                      solidAngle[ii][jj] = ratio              //testing only 
490                        xy = xx[ii]*yy[jj]
491                        data[ii][jj] *= xy*ratio
492                       
493                        // multiplicative correction for detector efficiency JBG memo det_eff_cor2.doc 3/20/07
494                        // correction inserted 11/2007 SRK
495                        // large angle detector efficiency correction is >= 1 and will "bump up" the highest angles
496                        // so divide here to get the correct answer (5/22/08 SRK)
497                        if(doEfficiency)
498#ifdef ILL_D22
499                                data[ii][jj]  /= DetEffCorrILL(lambda,dtdist,xd)                //tube-by-tube corrections
500                  solidAngle[ii][jj] = DetEffCorrILL(lambda,dtdist,xd)
501#else
502                                data[ii][jj] /= DetEffCorr(lambda,dtdist,xd,yd)
503        //                      solidAngle[ii][jj] = DetEffCorr(lambda,dtdist,xd,yd)            //testing only
504#endif
505                        endif
506                       
507                        // large angle transmission correction is <= 1 and will "bump up" the highest angles
508                        if(doTrans)
509                       
510                                if(trans<0.1 && ii==0 && jj==0)
511                                        Print "***transmission is less than 0.1*** and is a significant correction"
512                                endif
513                               
514                                if(trans==0)
515                                        if(ii==0 && jj==0)
516                                                Print "***transmission is ZERO*** and has been reset to 1.0 for the averaging calculation"
517                                        endif
518                                        trans = 1
519                                endif
520                                       
521                                data[ii][jj] /= LargeAngleTransmissionCorr(trans,dtdist,xd,yd)          //moved from 1D avg SRK 11/2007
522                                solidAngle[ii][jj] = LargeAngleTransmissionCorr(trans,dtdist,xd,yd)             //testing only
523                        endif
524                       
525                        jj+=1
526                while(jj<pixelsX)
527                ii+=1
528        while(ii<pixelsX)
529       
530        //clean up waves
531//      Killwaves/Z fyy,xx,yy
532       
533        Return(0)
534End
535
536//trig function used by DetCorr()
537Function dc_fx(x,sx,sx3,xcenter)
538        Variable x,sx,sx3,xcenter
539       
540        Variable result
541       
542        result = sx3*tan((x-xcenter)*sx/sx3)
543        Return(result)
544End
545
546//trig function used by DetCorr()
547Function dc_fy(y,sy,sy3,ycenter)
548        Variable y,sy,sy3,ycenter
549       
550        Variable result
551       
552        result = sy3*tan((y-ycenter)*sy/sy3)
553        Return(result)
554End
555
556//trig function used by DetCorr()
557Function dc_fxn(x,sx,sx3,xcenter)
558        Variable x,sx,sx3,xcenter
559       
560        Variable result
561       
562        result = (cos((x-xcenter)*sx/sx3))^2
563        Return(result)
564End
565
566//trig function used by DetCorr()
567Function dc_fym(y,sy,sy3,ycenter)
568        Variable y,sy,sy3,ycenter
569       
570        Variable result
571       
572        result = (cos((y-ycenter)*sy/sy3))^2
573        Return(result)
574End
575
576//distances passed in are in mm
577// dtdist is SDD
578// xd and yd are distances from the beam center to the current pixel
579//
580Function DetEffCorr(lambda,dtdist,xd,yd)
581        Variable lambda,dtdist,xd,yd
582       
583        Variable theta,cosT,ff,stAl,stHe
584       
585        theta = atan( (sqrt(xd^2 + yd^2))/dtdist )
586        cosT = cos(theta)
587       
588        stAl = 0.00967*lambda*0.8               //dimensionless, constants from JGB memo
589        stHe = 0.146*lambda*2.5
590       
591        ff = exp(-stAl/cosT)*(1-exp(-stHe/cosT)) / ( exp(-stAl)*(1-exp(-stHe)) )
592               
593        return(ff)
594End
595
596// DIVIDE the intensity by this correction to get the right answer
597Function LargeAngleTransmissionCorr(trans,dtdist,xd,yd)
598        Variable trans,dtdist,xd,yd
599
600        //angle dependent transmission correction
601        Variable uval,arg,cos_th,correction,theta
602       
603        ////this section is the trans_correct() VAX routine
604//      if(trans<0.1)
605//              Print "***transmission is less than 0.1*** and is a significant correction"
606//      endif
607//      if(trans==0)
608//              Print "***transmission is ZERO*** and has been reset to 1.0 for the averaging calculation"
609//              trans = 1
610//      endif
611       
612        theta = atan( (sqrt(xd^2 + yd^2))/dtdist )              //theta at the input pixel
613       
614        //optical thickness
615        uval = -ln(trans)               //use natural logarithm
616
617//      theta = 2*asin(lambda*qval/(4*pi))
618
619        cos_th = cos(theta)
620        arg = (1-cos_th)/cos_th
621        if((uval<0.01) || (cos_th>0.99))                //OR
622                //small arg, approx correction
623                correction= 1-0.5*uval*arg
624        else
625                //large arg, exact correction
626                correction = (1-exp(-uval*arg))/(uval*arg)
627        endif
628
629        //end of transmission/pathlength correction
630
631        return(correction)
632end
633
634//******************
635//direct port of the FORTRAN code for calculating the weighted
636//shifted element to add when beam centers in data headers do not match
637//(indices updated to [0,n-1] indexing rather than (1,n) of fortran
638//
639// as of IGOR 4.0, could be rewritten to pass-by-reference noadd, rather than wave, but the function
640// is so little used, it's not worth the time
641Function ShiftSum(DATA,ip,jp,XSHIFT,YSHIFT,noadd)
642        Wave data
643        Variable ip,jp,xshift,yshift
644        Wave noadd
645//
646//       COMPUTE WEIGHTED OFFSET ELEMENT SUM FOR USE IN SANS DATA
647//       ANALYSIS MODULES.
648//
649// "data" wave passed in is the current contents of the work file
650// sum_val is the return value of the function
651// "noadd" is passed back to the calling function as a one-point wave
652
653        Variable XDELTA,YDELTA,kk,II,JJ,ISHIFT,JSHIFT,sum_val
654        Make/O/N=4 iii,jjj,a
655
656//       -----------------------------------------------------------------
657
658        ISHIFT = trunc(XSHIFT)          // INTEGER PART, trunc gives int closest in dierction of zero
659        XDELTA = XSHIFT - ISHIFT        //FRACTIONAL PART.
660        JSHIFT = trunc(YSHIFT)
661        YDELTA = YSHIFT - JSHIFT
662        II = ip + ISHIFT
663        JJ = jp + JSHIFT
664
665//       SHIFT IS DEFINED AS A VECTOR ANCHORED AT THE STATIONARY CENTER
666//       AND POINTING TO THE MOVABLE CENTER.  THE MOVABLE FIELD IS THUS
667//       ACTUALLY MOVED BY -SHIFT.
668//
669        IF ((XDELTA>= 0) && (YDELTA >= 0))              // CASE I ---- "%&" is "and"
670                III[0] = II
671                JJJ[0] = JJ
672                III[1] = II + 1
673                JJJ[1] = JJ
674                III[2] = II + 1
675                JJJ[2] = JJ + 1
676                III[3] = II
677                JJJ[3] = JJ + 1
678                A[0] = (1. - XDELTA)*(1. - YDELTA)
679                A[1] = XDELTA*(1. - YDELTA)
680                A[2] = XDELTA*YDELTA
681                A[3] = (1. - XDELTA)*YDELTA
682        Endif
683        IF ((XDELTA >= 0) && (YDELTA < 0))              // CASE II.
684                III[0] = II
685                JJJ[0] = JJ
686                III[1] = II
687                JJJ[1] = JJ - 1
688                III[2] = II + 1
689                JJJ[2] = JJ - 1
690                III[3] = II + 1
691                JJJ[3] = JJ
692                A[0] = (1. - XDELTA)*(1. + YDELTA)
693                A[1] = (1. - XDELTA)*(-YDELTA)
694                A[2] = XDELTA*(-YDELTA)
695                A[3] = XDELTA*(1. + YDELTA)
696        Endif
697        IF ((XDELTA < 0) && (YDELTA >= 0))              // CASE III.
698                III[0] = II
699                JJJ[0] = JJ
700                III[1] = II
701                JJJ[1] = JJ + 1
702                III[2] = II - 1
703                JJJ[2] = JJ + 1
704                III[3] = II - 1
705                JJJ[3] = JJ
706                A[0] = (1. + XDELTA)*(1 - YDELTA)
707                A[1] = (1. + XDELTA)*YDELTA
708                A[2] = -XDELTA*YDELTA
709                A[3] = -XDELTA*(1. - YDELTA)
710        Endif
711        IF ((XDELTA < 0) && (YDELTA < 0))               //CASE IV.
712                III[0] = II
713                JJJ[0] = JJ
714                III[1] = II - 1
715                JJJ[1] = JJ
716                III[2] = II - 1
717                JJJ[2] = JJ - 1
718                III[3] = II
719                JJJ[3] = JJ - 1
720                A[0] = (1. + XDELTA)*(1. + YDELTA)
721                A[1] = -XDELTA*(1. + YDELTA)
722                A[2] = (-XDELTA)*(-YDELTA)
723                A[3] = (1. + XDELTA)*(-YDELTA)
724        Endif
725
726        NVAR pixelsX = root:myGlobals:gNPixelsX
727        NVAR pixelsY = root:myGlobals:gNPixelsY
728//check to see if iii[0],jjj[0] are valid detector elements, in [0,127]
729//if not set noadd[0] to 1, to let calling routine know NOT to add
730//        CALL TESTIJ(III(1),JJJ(1),OKIJ)
731        NOADD[0] = 0
732        if( (iii[0]<0) || (iii[0]>(pixelsX-1)) )
733                noadd[0] = 1
734        endif
735        if((jjj[0]<0) || (jjj[0]>(pixelsY-1)) )
736                noadd[0] = 1
737        endif
738       
739
740       
741        sum_val = 0.
742        kk = 0
743        Do
744                IF(JJJ[kk] == pixelsX)
745                        //do nothing
746                else
747                        sum_val += A[kk]*DATA[III[kk]][JJJ[kk]]
748                endif
749                kk+=1
750        while(kk<4)
751       
752        //clean up waves
753        KillWaves/z iii,jjj,a
754       
755        RETURN (sum_val)
756       
757End             //function ShiftSum
758
759//************************
760//unused testing procedure, may not be up-to-date with other procedures
761//check before re-implementing
762//
763Proc DIV_a_Workfile(type)
764        String type
765        Prompt type,"WORK data type",popup,"COR;SAM;EMP;BGD"
766       
767        //macro will take whatever is in SELECTED folder and DIVide it by the current
768        //contents of the DIV folder - the function will check for existence
769        //before proceeding
770       
771        Variable err
772        err = Divide_work(type)         //returns err = 1 if data doesn't exist in specified folders
773       
774        if(err)
775                Abort "error in Divide_work"
776        endif
777       
778        //contents are always dumped to CAL
779        type = "CAL"
780       
781        String newTitle = "WORK_"+type
782        DoWindow/F SANS_Data
783        DoWindow/T SANS_Data, newTitle
784        KillStrings/Z newTitle
785       
786        //need to update the display with "data" from the correct dataFolder
787        //reset the current displaytype to "type"
788        String/G root:myGlobals:gDataDisplayType=Type
789       
790        fRawWindowHook()
791       
792End
793
794//function will divide the contents of "type" folder with the contents of
795//the DIV folder
796// all data is converted to linear scale for the calculation
797//
798Function Divide_work(type)
799        String type
800       
801        //check for existence of data in type and DIV
802        // if the desired workfile doesn't exist, let the user know, and abort
803        String destPath=""
804        destPath = "root:Packages:NIST:"+Type + ":data"
805        if(WaveExists($destpath) == 0)
806                Print "There is no work file in "+type+"--Aborting"
807                Return(1)               //error condition
808        Endif
809        //check for DIV
810        // if the DIV workfile doesn't exist, let the user know,and abort
811        destPath = "root:Packages:NIST:DIV:data"
812        if(WaveExists($destpath) == 0)
813                Print "There is no work file in DIV --Aborting"
814                Return(1)               //error condition
815        Endif
816        //files exist, proceed
817       
818        //check for log-scaling of the "DIV" data and adjust if necessary
819        ConvertFolderToLinearScale("DIV")
820       
821        //copy type information to CAL, wiping out the old contents of the CAL folder first
822       
823        //destPath = "root:Packages:NIST:CAL"
824        //SetDataFolder destPath
825        //KillWaves/A/Z                 //get rid of the old data in CAL folder
826
827        //check for log-scaling of the "type" data and adjust if necessary
828        ConvertFolderToLinearScale(type)
829        //then continue
830
831        //copy from current dir (type)=destPath to CAL, overwriting CAL contents
832        destPath = "root:Packages:NIST:" + type
833        Duplicate/O $(destPath + ":data"),$"root:Packages:NIST:CAL:data"
834//      Duplicate/O $(destPath + ":vlegend"),$"root:Packages:NIST:CAL:vlegend"
835        Duplicate/O $(destPath + ":textread"),$"root:Packages:NIST:CAL:textread"
836        Duplicate/O $(destPath + ":integersread"),$"root:Packages:NIST:CAL:integersread"
837        Duplicate/O $(destPath + ":realsread"),$"root:Packages:NIST:CAL:realsread"
838        //need to save a copy of filelist string too (from the current type folder)
839        SVAR oldFileList = $(destPath + ":fileList")
840
841        //now switch to reference waves in CAL folder
842        destPath = "root:Packages:NIST:CAL"
843        //make appropriate wave references
844        Wave data=$(destPath + ":data")                                 // these wave references point to the data in CAL
845        Wave/t textread=$(destPath + ":textread")                       //that are to be directly operated on
846        Wave integersread=$(destPath + ":integersread")
847        Wave realsread=$(destPath + ":realsread")
848        Variable/G $(destPath + ":gIsLogScale")=0                       //make new flag in CAL folder, data is linear scale
849        //need to copy filelist string too
850        String/G $(destPath + ":fileList") = oldFileList
851
852        Wave div_data = $"root:Packages:NIST:DIV:data"          //hard-wired in....
853        //do the division, changing data in CAL
854        data /= div_data
855       
856        //update CAL header
857        textread[1] = date() + " " + time()             //date + time stamp
858       
859        Return(0)
860End
861
862//test procedure, not called anymore
863Proc AbsoluteScaling(type,c0,c1,c2,c3,c4,c5)
864        String type
865        Variable c0=1,c1=0.1,c2=0.95,c3=0.1,c4=1,c5=32.0
866        Prompt type,"WORK data type",popup,"CAL;COR;SAM"
867        Prompt c0, "Sample Transmission"
868        Prompt c1, "Sample Thickness (cm)"
869        Prompt c2, "Standard Transmission"
870        Prompt c3, "Standard Thickness (cm)"
871        Prompt c4, "I(0) from standard fit (normalized to 1E8 monitor cts)"
872        Prompt c5, "Standard Cross-Section (cm-1)"
873
874        Variable err
875        //call the function to do the math
876        //data from "type" will be scaled and deposited in ABS
877        err = Absolute_Scale(type,c0,c1,c2,c3,c4,c5)
878       
879        if(err)
880                Abort "Error in Absolute_Scale()"
881        endif
882       
883        //contents are always dumped to ABS
884        type = "ABS"
885       
886        String newTitle = "WORK_"+type
887        DoWindow/F SANS_Data
888        DoWindow/T SANS_Data, newTitle
889        KillStrings/Z newTitle
890       
891        //need to update the display with "data" from the correct dataFolder
892        //reset the current displaytype to "type"
893        String/G root:myGlobals:gDataDisplayType=Type
894       
895        fRawWindowHook()
896       
897End
898
899//s_ is the standard
900//w_ is the "work" file
901//both are work files and should already be normalized to 10^8 monitor counts
902Function Absolute_Scale(type,w_trans,w_thick,s_trans,s_thick,s_izero,s_cross)
903        String type
904        Variable w_trans,w_thick,s_trans,s_thick,s_izero,s_cross
905       
906        //convert the "type" data to absolute scale using the given standard information
907        //copying the "type" waves to ABS
908       
909        //check for existence of data, rescale to linear if needed
910        String destPath
911        //check for "type"
912        destPath = "root:Packages:NIST:"+Type + ":data"
913        if(WaveExists($destpath) == 0)
914                Print "There is no work file in "+type+"--Aborting"
915                Return(1)               //error condition
916        Endif
917        //check for log-scaling of the "type" data and adjust if necessary
918        destPath = "root:Packages:NIST:"+Type
919        NVAR gIsLogScale = $(destPath + ":gIsLogScale")
920        if(gIsLogScale)
921                Duplicate/O $(destPath + ":linear_data") $(destPath + ":data")//back to linear scale
922                Variable/G $(destPath + ":gIsLogScale")=0       //the "type" data is not logscale anymore
923        endif
924       
925        //copy "oldtype" information to ABS
926        //overwriting out the old contents of the ABS folder (/O option in Duplicate)
927        //copy over the waves data,vlegend,text,integers,reals(read)
928
929        String oldType= "root:Packages:NIST:"+type              //this is where the data to be absoluted is
930        //copy from current dir (type) to ABS, defined by destPath
931        Duplicate/O $(oldType + ":data"),$"root:Packages:NIST:ABS:data"
932//      Duplicate/O $(oldType + ":vlegend"),$"root:Packages:NIST:ABS:vlegend"
933        Duplicate/O $(oldType + ":textread"),$"root:Packages:NIST:ABS:textread"
934        Duplicate/O $(oldType + ":integersread"),$"root:Packages:NIST:ABS:integersread"
935        Duplicate/O $(oldType + ":realsread"),$"root:Packages:NIST:ABS:realsread"
936        //need to save a copy of filelist string too (from the current type folder)
937        SVAR oldFileList = $(oldType + ":fileList")
938        //need to copy filelist string too
939        String/G $"root:Packages:NIST:ABS:fileList" = oldFileList
940       
941        //now switch to ABS folder
942        //make appropriate wave references
943        WAVE data=$"root:Packages:NIST:ABS:data"                                        // these wave references point to the "type" data in ABS
944        WAVE/T textread=$"root:Packages:NIST:ABS:textread"                      //that are to be directly operated on
945        WAVE integersread=$"root:Packages:NIST:ABS:integersread"
946        WAVE realsread=$"root:Packages:NIST:ABS:realsread"
947        Variable/G $"root:Packages:NIST:ABS:gIsLogscale"=0                      //make new flag in ABS folder, data is linear scale
948       
949        //do the actual absolute scaling here, modifying the data in ABS
950        Variable defmon = 1e8,w_moncount,s1,s2,s3,s4
951       
952        w_moncount = realsread[0]               //monitor count in "type"
953        if(w_moncount == 0)
954                //zero monitor counts will give divide by zero ---
955                DoAlert 0,"Total monitor count in data file is zero. No rescaling of data"
956                Return(1)               //report error
957        Endif
958       
959        //calculate scale factor
960        s1 = defmon/realsread[0]                //[0] is monitor count (s1 should be 1)
961        s2 = s_thick/w_thick
962        s3 = s_trans/w_trans
963        s4 = s_cross/s_izero
964       
965        data *= s1*s2*s3*s4
966       
967        //********* 15APR02
968        // DO NOt correct for atenuators here - the COR step already does this, putting all of the data one equal
969        // footing (zero atten) before doing the subtraction.
970        //
971        //Print "ABS data multiplied by  ",s1*s2*s3*s4/attenFactor
972       
973        //update the ABS header information
974        textread[1] = date() + " " + time()             //date + time stamp
975       
976        Return (0) //no error
977End
978
979//*************
980// start of section of functions used for workfile math panel
981//*************
982
983
984//function will copy the contents of oldtype folder to newtype folder
985//converted to linear scale before copying
986//******data in newtype is overwritten********
987//
988Function CopyWorkContents(oldtype,newtype)
989        String oldtype,newtype
990       
991        //check for existence of data in oldtype
992        // if the desired workfile doesn't exist, let the user know, and abort
993        String destPath=""
994        destPath = "root:Packages:NIST:"+oldType + ":data"
995        if(WaveExists($destpath) == 0)
996                Print "There is no work file in "+oldtype+"--Aborting"
997                Return(1)               //error condition
998        Endif
999       
1000        //check for log-scaling of the "type" data and adjust if necessary
1001        ConvertFolderToLinearScale(oldtype)
1002        Fix_LogLinButtonState(0)                //make sure the button reflects the new linear scaling
1003        //then continue
1004
1005        //copy from current dir (type)=destPath to newtype, overwriting newtype contents
1006        destPath = "root:Packages:NIST:" + oldtype
1007        Duplicate/O $(destPath + ":data"),$("root:Packages:NIST:"+newtype+":data")
1008        Duplicate/O $(destPath + ":textread"),$("root:Packages:NIST:"+newtype+":textread")
1009        Duplicate/O $(destPath + ":integersread"),$("root:Packages:NIST:"+newtype+":integersread")
1010        Duplicate/O $(destPath + ":realsread"),$("root:Packages:NIST:"+newtype+":realsread")
1011        //need to save a copy of filelist string too (from the current type folder)
1012        SVAR oldFileList = $(destPath + ":fileList")
1013
1014        //now switch to reference waves in newtype folder
1015        destPath = "root:Packages:NIST:"+newtype
1016        Variable/G $(destPath + ":gIsLogScale")=0                       //make new flag in newtype folder, data is linear scale
1017        //need to copy filelist string too
1018        String/G $(destPath + ":fileList") = oldFileList
1019
1020        Return(0)
1021End
1022
1023//Entry procedure from main panel
1024//
1025Proc CopyWorkFolder(oldType,newType)
1026        String oldType,newType
1027        Prompt oldType,"Source WORK data type",popup,"SAM;EMP;BGD;DIV;COR;CAL;RAW;ABS;STO;SUB;DRK;"
1028        Prompt newType,"Destination WORK data type",popup,"SAM;EMP;BGD;DIV;COR;CAL;RAW;ABS;STO;SUB;DRK;"
1029//      Prompt oldType,"Source WORK data type",popup,"AAA;BBB;CCC;DDD;EEE;FFF;GGG;"
1030//      Prompt newType,"Destination WORK data type",popup,"AAA;BBB;CCC;DDD;EEE;FFF;GGG;"
1031
1032        // data folder "old" will be copied to "new" (and will overwrite)
1033        CopyWorkContents(oldtype,newtype)
1034End
1035
1036//initializes datafolder and constants necessary for the workfilemath panel
1037//
1038Proc Init_WorkMath()
1039        //create the data folder
1040        //String str = "AAA;BBB;CCC;DDD;EEE;FFF;GGG;"
1041        String str = "File_1;File_2;Result;"
1042        NewDataFolder/O/S root:Packages:NIST:WorkMath
1043        String/G gFolderList=str
1044        Variable ii=0,num=itemsinlist(str)
1045        do
1046                Execute "NewDataFolder/O "+StringFromList(ii, str ,";")
1047                ii+=1
1048        while(ii<num)
1049        Variable/G const1=1,const2=1
1050       
1051        SetDataFolder root:
1052End
1053
1054//entry procedure to invoke the workfilemath panel, initializes if needed
1055//
1056Proc Show_WorkMath_Panel()
1057        DoWindow/F WorkFileMath
1058        if(V_flag==0)
1059                Init_WorkMath()
1060                WorkFileMath()
1061        Endif
1062End
1063
1064//attempts to perform the selected math operation based on the selections in the panel
1065// aborts with an error condition if operation can't be completed
1066// or puts the final answer in the Result folder, and displays the selected data
1067//
1068Function WorkMath_DoIt_ButtonProc(ctrlName) : ButtonControl
1069        String ctrlName
1070
1071        String str1,str2,oper,dest = "Result"
1072        String pathStr,workMathStr="WorkMath:"
1073       
1074        //get the panel selections (these are the names of the files on disk)
1075        PathInfo catPathName
1076        pathStr=S_Path
1077        ControlInfo popup0
1078        str1=S_Value
1079        ControlInfo popup1
1080        str2=S_Value
1081        ControlInfo popup2
1082        oper=S_Value
1083       
1084        //check that something has been selected for operation and destination
1085        if(cmpstr(oper,"Operation")==0)
1086                Abort "Select a math operand from the popup"
1087        Endif
1088
1089        //constants from globals
1090        NVAR const1=root:Packages:NIST:WorkMath:const1
1091        NVAR const2=root:Packages:NIST:WorkMath:const2
1092        Printf "(%g)%s %s (%g)%s = %s\r", const1,str1,oper,const2,str2,dest
1093        //check for proper folders (all 3 must be different)
1094       
1095        //load the data in here...
1096        //set #1
1097        Load_NamedASC_File(pathStr+str1,workMathStr+"File_1")
1098       
1099        NVAR pixelsX = root:myGlobals:gNPixelsX         //OK, location is correct
1100        NVAR pixelsY = root:myGlobals:gNPixelsY
1101       
1102        WAVE/Z data1=$("root:Packages:NIST:"+workMathStr+"File_1:data")
1103        If(cmpstr(str2,"UNIT MATRIX")==0)
1104                Make/O/N=(pixelsX,pixelsY) root:Packages:NIST:WorkMath:data             //don't put in File_2 folder
1105                Wave/Z data2 =  root:Packages:NIST:WorkMath:data                        //it's not real data!
1106                data2=1
1107        else
1108                //Load set #2
1109                Load_NamedASC_File(pathStr+str2,workMathStr+"File_2")
1110                WAVE/Z data2=$("root:Packages:NIST:"+workMathStr+"File_2:data")
1111        Endif
1112
1113        ///////
1114       
1115        //now that we know that data exists, convert each of the operands to linear scale
1116        ConvertFolderToLinearScale(workMathStr+"File_1")
1117        If(cmpstr(str2,"UNIT MATRIX")!=0)
1118                ConvertFolderToLinearScale(workMathStr+"File_2")                //don't need to convert unit matrix to linear
1119        endif
1120        //copy contents of str1 folder to dest and create the wave ref (it will exist)
1121        CopyWorkContents(workMathStr+"File_1",workMathStr+dest)
1122        WAVE/Z destData=$("root:Packages:NIST:"+workMathStr+dest+":data")
1123       
1124        //dispatch
1125        strswitch(oper)
1126                case "*":               //multiplication
1127                        destData = const1*data1 * const2*data2
1128                        break   
1129                case "_":               //subtraction
1130                        destData = const1*data1 - const2*data2
1131                        break
1132                case "/":               //division
1133                        destData = (const1*data1) / (const2*data2)
1134                        break
1135                case "+":               //addition
1136                        destData = const1*data1 + const2*data2
1137                        break                   
1138        endswitch
1139       
1140        //show the result
1141        WorkMath_Display_PopMenuProc("",0,"Result")
1142End
1143
1144// closes the panel and kills the data folder when done
1145//
1146Function WorkMath_Done_ButtonProc(ctrlName) : ButtonControl
1147        String ctrlName
1148       
1149        DoAlert 1,"Closing the panel will kill all of the data you have loaded into memory. Do you want to continue?"
1150        If(V_Flag==2)
1151                return(0)               //don't do anything
1152        Endif
1153        //kill the panel
1154        DoWindow/K WorkFileMath
1155        //wipe out the data folder of globals
1156        SVAR dataType=root:myGlobals:gDataDisplayType
1157        if(strsearch(dataType, "WorkMath", 0 ) != -1)           //kill the SANS_Data graph if needed
1158                DoWindow/K SANS_Data
1159        Endif
1160        KillDataFolder root:Packages:NIST:WorkMath
1161End
1162
1163// loads data into the specified folder
1164//
1165// currently unused since button has been removed from panel
1166//
1167Function WorkMath_Load_ButtonProc(ctrlName) : ButtonControl
1168        String ctrlName
1169       
1170        String destStr=""
1171        SVAR folderList=root:Packages:NIST:WorkMath:gFolderList
1172        Prompt destStr,"Select the destination folder",popup,folderList
1173        DoPrompt "Folder for ASC Load",destStr
1174       
1175        if(V_flag==1)
1176                return(1)               //user abort, do nothing
1177        Endif
1178       
1179        String destFolder = "WorkMath:"+destStr
1180       
1181        Load_ASC_File("Pick the ASC file",destFolder)
1182End
1183
1184// changes the display of the SANS_Data window based on popped data type
1185// first loads in the data from the File1 or File2 popup as needed
1186// then displays the selcted dataset, if it exists
1187// makes use of procedure from DisplayUtils
1188//
1189// - Always replaces File1 or File2 with fresh data from disk
1190//
1191Function WorkMath_Display_PopMenuProc(ctrlName,popNum,popStr) : PopupMenuControl
1192        String ctrlName
1193        Variable popNum
1194        String popStr
1195       
1196        String folder="WorkMath:",pathStr,str1
1197
1198        PathInfo catPathName
1199        pathStr=S_Path
1200       
1201        //if display result, just do it and return
1202        if(cmpstr(popStr,"Result")==0)
1203                Execute "ChangeDisplay(\""+folder+popstr+"\")"
1204                return(0)
1205        endif
1206        // if file1 or file2, load in the data and display
1207        if(cmpstr(popStr,"File_1")==0)
1208                ControlInfo popup0
1209                str1 = S_Value
1210        Endif
1211        if(cmpstr(popStr,"File_2")==0)
1212                ControlInfo popup1
1213                str1 = S_Value
1214        Endif
1215        //don't load or display the unit matrix
1216        Print str1
1217        if(cmpstr(str1,"UNIT MATRIX")!=0)
1218                Load_NamedASC_File(pathStr+str1,folder+popStr)
1219                //change the display
1220                Execute "ChangeDisplay(\""+folder+popstr+"\")"
1221        endif
1222        return(0)       
1223End
1224
1225//simple panel to do workfile arithmetic
1226//
1227Proc WorkFileMath()
1228        PauseUpdate; Silent 1           // building window...
1229        NewPanel /W=(610,211,880,490)/K=2 as "Work File Math"           // replace /K=2 flag
1230        DoWindow/C WorkFileMath
1231        ModifyPanel cbRGB=(47802,54484,6682)
1232        ModifyPanel fixedSize=1
1233        SetDrawLayer UserBack
1234        DrawLine 6,166,214,166
1235        SetDrawEnv fstyle= 4
1236        DrawText 10,34,"File #1:"
1237        SetDrawEnv fstyle= 4
1238        DrawText 13,129,"File #2:"
1239        DrawText 78,186,"= Result"
1240        Button button0,pos={28,245},size={50,20},proc=WorkMath_DoIt_ButtonProc,title="Do It"
1241        Button button0,help={"Performs the specified arithmetic"}
1242        Button button1,pos={183,245},size={50,20},proc=WorkMath_Done_ButtonProc,title="Done"
1243        Button button1,help={"Closes the panel"}
1244//      Button button2,pos={30,8},size={110,20},proc=WorkMath_Load_ButtonProc,title="Load ASC Data"
1245//      Button button2,help={"Loads ASC data files into the specified folder"}
1246        Button button3,pos={205,8},size={25,20},proc=ShowWorkMathHelp,title="?"
1247        Button button3,help={"Show help file for math operations on 2-D data sets"}
1248        SetVariable setvar0,pos={9,46},size={70,15},title=" "
1249        SetVariable setvar0,limits={-Inf,Inf,0},value= root:Packages:NIST:WorkMath:const1
1250        SetVariable setvar0,help={"Multiplicative constant for the first dataset"}
1251        PopupMenu popup0,pos={89,44},size={84,20},title="X  "
1252        PopupMenu popup0,mode=1,popvalue="1st Set",value= ASC_FileList()
1253        PopupMenu popup0,help={"Selects the first dataset for the operation"}
1254        PopupMenu popup1,pos={93,136},size={89,20},title="X  "
1255        PopupMenu popup1,mode=1,popvalue="2nd Set",value= "UNIT MATRIX;"+ASC_FileList()
1256        PopupMenu popup1,help={"Selects the second dataset for the operation"}
1257        PopupMenu popup2,pos={50,82},size={70,20},title="Operator  "
1258        PopupMenu popup2,mode=3,popvalue="Operation",value= #"\"+;_;*;/;\""
1259        PopupMenu popup2,help={"Selects the mathematical operator"}
1260        SetVariable setvar1,pos={13,139},size={70,15},title=" "
1261        SetVariable setvar1,limits={-Inf,Inf,0},value= root:Packages:NIST:WorkMath:const2
1262        SetVariable setvar1,help={"Multiplicative constant for the second dataset"}
1263//      PopupMenu popup3,pos={27,167},size={124,20},title=" = Destination"
1264//      PopupMenu popup3,mode=1,popvalue="Destination",value= root:Packages:NIST:WorkMath:gFolderList
1265//      PopupMenu popup3,help={"Selects the destination folder"}
1266        PopupMenu popup4,pos={55,204},size={103,20},proc=WorkMath_Display_PopMenuProc,title="Display"
1267        PopupMenu popup4,mode=3,value= "File_1;File_2;Result;"
1268        PopupMenu popup4,help={"Displays the data in the specified folder"}
1269EndMacro
1270
1271//jump to the help topic
1272Function ShowWorkMathHelp(ctrlName) : ButtonControl
1273        String ctrlName
1274        DisplayHelpTopic/Z/K=1 "SANS Data Reduction Tutorial[2-D Work File Arithmetic]"
1275        if(V_flag !=0)
1276                DoAlert 0,"The SANS Data Reduction Tutorial Help file could not be found"
1277        endif
1278End
1279
1280//utility function to clear the contents of a data folder
1281//won't clear data that is in use -
1282//
1283Function ClearDataFolder(type)
1284        String type
1285       
1286        SetDataFolder $("root:Packages:NIST:"+type)
1287        KillWaves/a/z
1288        KillStrings/a/z
1289        KillVariables/a/z
1290        SetDataFolder root:
1291End
1292
1293
1294
1295//fileStr must be the FULL path and filename on disk
1296//destFolder is the path to the Igor folder where the data is to be deposited
1297// - "Packages:NIST:WorkMath:File_1" for example, compatible with SANS_Data display type
1298//
1299Function Load_NamedASC_File(fileStr,destFolder)
1300        String fileStr,destFolder
1301
1302        Variable refnum
1303       
1304        //read in the data
1305        ReadASCData(fileStr,destFolder)
1306
1307        //the calling macro must change the display type
1308        String/G root:myGlobals:gDataDisplayType=destFolder
1309       
1310        FillFakeHeader_ASC(destFolder)          //uses info on the panel, if available
1311
1312        //data is displayed here, and needs header info
1313       
1314        fRawWindowHook()
1315       
1316        return(0)
1317End
1318
1319
1320//function called by the main entry procedure (the load button)
1321//loads data into the specified folder, and wipes out what was there
1322//
1323//aborts if no file was selected
1324//
1325// reads the data in if all is OK
1326//
1327// currently unused, as load button has been replaced
1328//
1329Function Load_ASC_File(msgStr,destFolder)
1330        String msgStr,destFolder
1331
1332        String filename="",pathStr=""
1333        Variable refnum
1334
1335        //check for the path
1336        PathInfo catPathName
1337        If(V_Flag==1)           //      /D does not open the file
1338                Open/D/R/T="????"/M=(msgStr)/P=catPathName refNum
1339        else
1340                Open/D/R/T="????"/M=(msgStr) refNum
1341        endif
1342        filename = S_FileName           //get the filename, or null if canceled from dialog
1343        if(strlen(filename)==0)
1344                //user cancelled, abort
1345                SetDataFolder root:
1346                Abort "No file selected, action aborted"
1347        Endif
1348       
1349        //read in the data
1350        ReadASCData(filename,destFolder)
1351
1352        //the calling macro must change the display type
1353        String/G root:myGlobals:gDataDisplayType=destFolder
1354       
1355        FillFakeHeader_ASC(destFolder)          //uses info on the panel, if available
1356
1357        //data is displayed here, and needs header info
1358       
1359        fRawWindowHook()
1360       
1361        return(0)
1362End
1363
1364
1365
1366//function called by the popups to get a file list of data that can be sorted
1367// this procedure simply removes the raw data files from the string - there
1368//can be lots of other junk present, but this is very fast...
1369//
1370Function/S ASC_FileList()
1371
1372        String list="",newList="",item=""
1373        Variable num,ii
1374       
1375        //check for the path
1376        PathInfo catPathName
1377        if(V_Flag==0)
1378                DoAlert 0, "Data path does not exist - pick the data path from the button on the main panel"
1379                Return("")
1380        Endif
1381       
1382        list = IndexedFile(catpathName,-1,"????")
1383        num=ItemsInList(list,";")
1384        //print "num = ",num
1385        for(ii=(num-1);ii>=0;ii-=1)
1386                item = StringFromList(ii, list  ,";")
1387                //simply remove all that are not raw data files (SA1 SA2 SA3)
1388                if( !stringmatch(item,"*.SA1*") && !stringmatch(item,"*.SA2*") && !stringmatch(item,"*.SA3*") )
1389                        if( !stringmatch(item,".*") && !stringmatch(item,"*.pxp") && !stringmatch(item,"*.DIV"))                //eliminate mac "hidden" files, pxp, and div files
1390                                if(!stringmatch(item,"*.AVE") && !stringmatch(item,"*.ABS"))
1391                                        newlist += item + ";"
1392                                endif
1393                        endif
1394                endif
1395        endfor
1396        //remove VAX version numbers
1397        newList = RemoveVersNumsFromList(newList)
1398        //sort
1399        newList = SortList(newList,";",0)
1400
1401        return newlist
1402End
Note: See TracBrowser for help on using the repository browser.