source: sans/Release/trunk/NCNR_User_Procedures/SANS/Reduction/WorkFileUtils.ipf @ 338

Last change on this file since 338 was 338, checked in by srkline, 15 years ago

merging structural changes from Dev/trunk into Release/trunk

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