source: sans/SANSReduction/branches/kline_29MAR07/Put in User Procedures/SANS_Reduction_v5.00/WorkFileUtils.ipf @ 80

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

cleaned unused code from WorkFileUtils?.ipf
added comments to NCNR_Utils.ipf

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