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

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

Several changes:

New version of ILL_DataReadWrite. Some changes added to Lionel's work to get the transmission calculation working corectly.

Changes to the wrapper to get the cursors on/off working correctly, as well as USANS matrix recalculation during normal fitting and during Global fitting. It may ask to recalculate the matrix occasionally when using the full data set - even though it really doesn't need to - but this is as a precaution.

Re-worked the header of the GRASP-export ASCII data to much more closely match the VAX output. I couldn't find any problem with the data block, so maybe GRASP was having trouble with the header.

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