source: sans/SANSReduction/trunk/Put in User Procedures/SANS_Reduction_v5.00/WorkFileUtils.ipf @ 41

Last change on this file since 41 was 41, checked in by srkline, 16 years ago

change to UNIX line endings

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