source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS/HFIR_DataReadWrite.ipf @ 940

Last change on this file since 940 was 940, checked in by srkline, 9 years ago

Updated the reduction Read/Write? and corresponding factility stubs to accomodate detector dead time written to the VAX header. It is currently not written to the header, but may be with NICE (hopefully).

With the move of NG3 SANS to CGB(upper), the NG3 designation in the account name [NGxSANSxx] has been replaced with CGB. Folders on charlotte and radio button on SASCALC are labeled "NGB30" to be more obvious which instrument it is.

FFT routines have minor typos cleaned up.

File size: 59.5 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=5.0
3#pragma IgorVersion=6.1
4
5//*************************************************************************************************
6//
7// Vers. ????
8// Vers. ???? - branched from main reduction to split out facility
9//                     specific calls
10//
11///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
12//                                      NIST CNR Igor Pro Data Reduction Package
13//                                 HFIR SANS version for SPICE raw data format:
14//
15//                                              University of Tennessee / NIST
16//                                                         DANSE/SANS
17//                                                              Jun. 2009: JHC
18///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
19//
20// - RAW data files are read into the RAW folder - integer data from the detector
21//   is decompressed and given the proper orientation
22// - header information is placed into real,integer, or text waves in the order they appear
23//   in the file header
24//
25// Work data (DIV File) is read into the DIV folder
26//
27//*************************************************************************************************
28
29//simple, main entry procedure that will load a RAW sans data file (not a work file)
30//into the RAW dataFolder. It is up to the calling procedure to display the file
31//
32// called by MainPanel.ipf and ProtocolAsPanel.ipf
33//
34Function LoadRawSANSData(msgStr)
35        String msgStr
36
37        String filename = ""
38
39        //each routine is responsible for checking the current (displayed) data folder
40        //selecting it, and returning to root when done
41        PathInfo/S catPathName          //should set the next dialog to the proper path...
42        //get the filename, then read it in
43        filename = PromptForPath(msgStr)//in SANS_Utils.ipf
44       
45        //check for cancel from dialog
46        if(strlen(filename)==0)
47                //user cancelled, abort
48                SetDataFolder root:
49                DoAlert 0, "No file selected, action aborted"
50                return(1)
51        Endif
52       
53        Variable t1=ticks
54       
55        variable error
56        String errorMsg
57       
58        error=ReadHeaderAndData(filename)       //this is the full Path+file
59
60        if (error < 0)
61                String windowName =""
62                switch(error)                                   // fileID holds the return code; check it
63                        case -1:                       
64                                //errorMsg = filename+ ": \r\t Failed to parse XML..."          //No Alert for this case...
65                                break
66                        case -2:                       
67                                //errorMsg = filename+ ": \r\t Either not found or cannot be opened for reading..."             //No Alert for this case...
68                                break
69                        case -3:
70                                errorMsg =  "\r\t XMLutils needs an upgrade:  http://www.igorexchange.com/project/XMLutils"
71                                break
72                        case -4:
73                                errorMsg = filename+ " ===> Not supported version of xml or SPICE..."   
74                                break
75                endswitch
76                SetDataFolder root:
77                //print "Failed loading", filename, "..."
78                DoAlert 0, errorMsg
79                //Clean up waves...
80                //KillWaves/Z M_listAttr, nsList,W_xmlcontentnodes
81                return(1)               //Do not change.
82        endif
83///***** done by a call to UpdateDisplayInformation()
84//      //the calling macro must change the display type
85//      String/G root:myGlobals:gDataDisplayType="RAW"          //displayed data type is raw
86//     
87//      //data is displayed here
88//      fRawWindowHook()
89        SetDataFolder root:
90       
91        Print "Time to load and display (s) = ",(ticks-t1)/60.15
92        Return(0)               //Do not change.
93End
94
95
96//function that does the guts of reading the binary data file
97//fname is the full path:name;vers required to open the file
98//VAX record markers are skipped as needed
99//VAX data as read in is in compressed I*2 format, and is decompressed
100//immediately after being read in. The final root:RAW:data wave is the real
101//neutron counts and can be directly operated on
102//
103// header information is put into three waves: integersRead, realsRead, and textRead
104// logicals in the header are currently skipped, since they are no use in the
105// data reduction process.
106//
107// The output is the three R/T/I waves that are filled at least with minimal values
108// and the detector data loaded into an array named "data"
109//
110// see documentation for the expected information in each element of the R/T/I waves
111// and the minimum set of information. These waves can be increased in length so that
112// more information can be accessed as needed (propagating changes...)
113//
114// called by multiple .ipfs (when the file name is known)
115//
116Function ReadHeaderAndData(filename)
117        String filename
118       
119        String curPath = "root:Packages:NIST:RAW:"     
120        //***NOTE ****
121        // the "current path" gets mysteriously reset to "root:" after the SECOND pass through
122        // this read routine, after the open dialog is presented
123        // the "--read" waves end up in the correct folder, but the data does not! Why?
124        //must re-set data folder before writing data array (done below)
125        SetDataFolder curPath   
126        //full filename and path is now passed in...
127        //actually open the file
128        //Open/R refNum as fname
129        STRING/G errorMsg       
130        Variable refNum,t1=ticks
131        //print "Loading", filename, "..."     
132        if (stringmatch(filename,"*.xml") <1)
133                //print "\r  ==> Failed: Not a *.xml file."
134                return (-1)                             //Not *.xml. Do nothing...
135        endif
136        //actually open the file
137        refNum = XmlOpenFile(filename) 
138        if (refNum < 0)
139                XmlCloseFile(refNum,0)
140                //print "\r  ==> Failed: Not a standard xml file format."
141                return (-2)                             //Not a xml file. Do nothing...
142        endif
143       
144        /////////////////////////////////////////////////////////////////////////////////////////////////\/\/\/\/ from P. R. Jemian     
145        //      test to see if XMLutils has the needed upgrade
146        XMLlistXpath(refNum, "/*", "") 
147        IF ( EXISTS( "M_listXPath" ) == 0 )
148                XmlCloseFile(refNum,0)
149                //errorMsg = "XMLutils needs an upgrade:  http://www.igorexchange.com/project/XMLutils"
150       
151                SetDataFolder root:
152                RETURN(-3)                                              // XOPutils needs an upgrade
153        ENDIF
154        ///////////////////////////////////////////////////////////////////////////////////////////////\/\/\/\ from P. R. Jemian
155       
156        // Check if  it is the SPICE version = 1.1
157        String ns_ver = "1.1"
158        Variable ns = 0
159        ns = str2num(XMLstrFmXpath(refNum, "//SPICErack/@SPICE_version","",""))
160       
161        // older version       
162        if (ns <1.1)
163                //errorMsg = filename + ": This SPICE version is not supported"
164                XmlCloseFile(refNum,0)
165                SetDataFolder root:
166                return (-4)
167        endif
168       
169        //this function is for reading in RAW data only, so it will always put data in RAW folder
170       
171        String curFolder="RAW"
172        SetDataFolder curPath           //use the full path, so it will always work
173        Variable/G root:Packages:NIST:RAW:gIsLogScale = 0               //initial state is linear, keep this in RAW folder
174        Variable integer,realval
175        String sansfname,textstr
176       
177        Make/O/N=23 $"root:Packages:NIST:RAW:IntegersRead"
178        Make/O/N=52 $"root:Packages:NIST:RAW:RealsRead"
179        Make/O/T/N=11 $"root:Packages:NIST:RAW:TextRead"
180       
181        Wave intw=$"root:Packages:NIST:RAW:IntegersRead"
182        Wave realw=$"root:Packages:NIST:RAW:RealsRead"
183        Wave/T textw=$"root:Packages:NIST:RAW:TextRead"
184       
185        //Make/O/N=16384 $"root:Pacakges:NIST:RAW:data"
186        //WAVE data=$"root:Packages:NIST:RAW:data"
187       
188        //intw = 0
189        //realw = 0
190        //textw = ""
191       
192       
193        //Redimension/N=(192,192) data                  //NIST raw data is 128x128 - do not generalize
194        //data =0
195       
196        //ORNL HFIR SANS DATA
197        String tempheadhfir =""
198       ReadHFIRSansRaw(refNum,curFolder,tempheadhfir)
199
200       //Take the file name from "actual file name", not from the header: (JC found some cases that those are different.)
201       //This  can be removed where the problem is solved....
202       textw[0]=GetFName(filename,  1)
203
204        SetDataFolder curPath
205        String/G fileList = textw[0]
206        //return the data folder to root
207       
208        WAVE data=$"root:Packages:NIST:RAW:data"
209        Duplicate/O data linear_data                    // data is "fresh" and linear scale, so copy it now
210               
211        // proper error for counting statistics, good for low count values too
212        // rather than just sqrt(n)
213        // see N. Gehrels, Astrophys. J., 303 (1986) 336-346, equation (7)
214        // for S = 1 in eq (7), this corresponds to one sigma error bars
215        Duplicate/O linear_data linear_data_error
216        linear_data_error = 1 + sqrt(linear_data + 0.75)                               
217        //
218       
219        SetDataFolder root:
220
221        Return 0
222
223End
224
225
226//****************
227//main entry procedure for reading a "WORK.DIV" file
228//displays a quick image of the  file, to check that it's correct
229//data is deposited in root:DIV data folder
230//
231// local, currently unused
232//
233//
234
235Proc ReadWork_DIV()
236       
237        String fname = PromptForPath("Select detector sensitivity file")
238        ReadHeaderAndWork("DIV",fname)          //puts what is read in work.div
239       
240        String waveStr = "root:Packages:NIST:DIV:data"
241        NewImage/F/K=1/S=2 $waveStr             //this is an experimental IGOR operation
242        ModifyImage '' ctab= {*,*,YellowHot,0}
243
244        String/G root:Packages:NIST:DIV:fileList = "WORK.DIV"
245       
246        SetDataFolder root:             //(redundant)
247End
248
249
250//this function is the guts of reading a binary VAX file of real (4-byte) values
251// (i.e. a WORK.aaa file)
252// work files have the same header structure as RAW SANS data, just with
253//different data (real, rather than compressed integer data)
254//
255//************
256//this routine incorrectly reads in several data values where the VAX record
257//marker splits the 4-byte real (at alternating record markers)
258//this error seems to not be severe, but shoud be corrected (at great pain)
259//************
260//
261// called from ProtocolAsPanel.ipf
262//
263//
264Function ReadHeaderAndWork(type,fname)
265        String type,fname
266       
267        //type is the desired folder to read the workfile to
268        //this data will NOT be automatically displayed gDataDisplayType is unchanged
269
270//      SVAR cur_folder=root:myGlobals:gDataDisplayType
271        String cur_folder = type
272        String curPath = "root:Packages:NIST:"+cur_folder
273        SetDataFolder curPath           //use the full path, so it will always work
274       
275        Variable refNum,integer,realval
276        String sansfname,textstr
277        Variable/G $(curPath + ":gIsLogScale") = 0              //initial state is linear, keep this in DIV folder
278       
279        Make/O/N=23 $(curPath + ":IntegersRead")
280        Make/O/N=52 $(curPath + ":RealsRead")
281        Make/O/T/N=11 $(curPath + ":TextRead")
282       
283        WAVE intw=$(curPath + ":IntegersRead")
284        WAVE realw=$(curPath + ":RealsRead")
285        WAVE/T textw=$(curPath + ":TextRead")
286       
287        //***NOTE ****
288        // the "current path" gets mysteriously reset to "root:" after the SECOND pass through
289        // this read routine, after the open dialog is presented
290        // the "--read" waves end up in the correct folder, but the data does not! Why?
291        //must re-set data folder before writing data array (done below)
292       
293        SetDataFolder curPath
294        if (stringmatch(fname,"*.xml") <1)
295                return 0                                //Not *.xml. Do nothing...
296        endif
297        //actually open the file
298        refNum = XmlOpenFile(fname)     
299        if (refNum < 0)
300                XMLclosefile(refNum, 0)
301                return 0                                //Not a xml file. Do nothing...
302        endif
303       
304        //ORNL HFIR SANS DATA
305        String tempheadhfir =""
306       ReadHFIRSansRaw(refNum,cur_folder,tempheadhfir)
307
308        //Take the file name from "actual file name", not from the header: (JC found some cases that those are different.)
309       //This  can be removed where the problem is solved....
310       textw[0]=GetFName(fname,  1)
311       
312        //keep a string with the filename in the DIV folder
313        String/G $(curPath + ":fileList") = textw[0]
314
315        WAVE data=$"root:Packages:NIST:RAW:data"
316        Duplicate/O data $"root:Packages:NIST:RAW:linear_data"                  // data is "fresh" and linear scale, so copy it now
317       
318        //return the data folder to root
319        SetDataFolder root:
320        Return(0)
321End
322
323/////   ASC FORMAT READER  //////
324/////   FOR WORKFILE MATH PANEL //////
325
326//function to read in the ASC output of SANS reduction
327// currently the file has 20 header lines, followed by a single column
328// of 16384 values, Data is written by row, starting with Y=1 and X=(1->128)
329//
330//returns 0 if read was ok
331//returns 1 if there was an error
332//
333// called by WorkFileUtils.ipf
334//
335Function ReadASCData(fname,destPath)
336        String fname, destPath
337        //this function is for reading in ASCII data so put data in user-specified folder
338        SetDataFolder "root:"+destPath
339
340        NVAR pixelsX = root:myGlobals:gNPixelsX
341        NVAR pixelsY = root:myGlobals:gNPixelsY
342        Variable refNum=0,ii,p1,p2,tot,num=pixelsX,numHdrLines=20
343        String str=""
344        //data is initially linear scale
345        Variable/G :gIsLogScale=0
346        Make/O/T/N=(numHdrLines) hdrLines
347        Make/O/D/N=(pixelsX*pixelsY) data                       //,linear_data
348       
349        //full filename and path is now passed in...
350        //actually open the file
351//      SetDataFolder destPath
352        Open/R/Z refNum as fname                // /Z flag means I must handle open errors
353        if(refnum==0)           //FNF error, get out
354                DoAlert 0,"Could not find file: "+fname
355                Close/A
356                SetDataFolder root:
357                return(1)
358        endif
359        if(V_flag!=0)
360                DoAlert 0,"File open error: V_flag="+num2Str(V_Flag)
361                Close/A
362                SetDataFolder root:
363                return(1)
364        Endif
365        //
366        for(ii=0;ii<numHdrLines;ii+=1)          //read (or skip) 18 header lines
367                FReadLine refnum,str
368                hdrLines[ii]=str
369        endfor
370        //     
371        Close refnum
372       
373//      SetDataFolder destPath
374        LoadWave/Q/G/D/N=temp fName
375        Wave/Z temp0=temp0
376        data=temp0
377        Redimension/N=(pixelsX,pixelsY) data            //,linear_data
378
379        Duplicate/O data linear_data_error
380        linear_data_error = 1 + sqrt(data + 0.75)
381       
382        //just in case there are odd inputs to this, like negative intensities
383        WaveStats/Q linear_data_error
384        linear_data_error = numtype(linear_data_error[p]) == 0 ? linear_data_error[p] : V_avg
385        linear_data_error = linear_data_error[p] != 0 ? linear_data_error[p] : V_avg
386               
387        //linear_data = data
388       
389        KillWaves/Z temp0
390        Close/A
391        //return the data folder to root
392        SetDataFolder root:
393       
394        Return(0)
395End
396
397// fills the "default" fake header so that the SANS Reduction machinery does not have to be altered
398// pay attention to what is/not to be trusted due to "fake" information.
399// uses what it can from the header lines from the ASC file (hdrLines wave)
400//
401// destFolder is of the form "myGlobals:WorkMath:AAA"
402//
403//
404// called by WorkFileUtils.ipf
405//
406Function FillFakeHeader_ASC(destFolder)
407        String destFolder
408        Make/O/N=23 $("root:"+destFolder+":IntegersRead")
409        Make/O/N=52 $("root:"+destFolder+":RealsRead")
410        Make/O/T/N=11 $("root:"+destFolder+":TextRead")
411       
412        Wave intw=$("root:"+destFolder+":IntegersRead")
413        Wave realw=$("root:"+destFolder+":RealsRead")
414        Wave/T textw=$("root:"+destFolder+":TextRead")
415       
416        //Put in appropriate "fake" values
417        //parse values as needed from headerLines
418        Wave/T hdr=$("root:"+destFolder+":hdrLines")
419        Variable monCt,lam,offset,sdd,trans,thick
420        Variable xCtr,yCtr,a1,a2,a1a2Dist,dlam,bsDiam
421        String detTyp=""
422        String tempStr="",formatStr="",junkStr=""
423        formatStr = "%g %g %g %g %g %g"
424        tempStr=hdr[3]
425        sscanf tempStr, formatStr, monCt,lam,offset,sdd,trans,thick
426//      Print monCt,lam,offset,sdd,trans,thick,avStr,step
427        formatStr = "%g %g %g %g %g %g %g %s"
428        tempStr=hdr[5]
429        sscanf tempStr,formatStr,xCtr,yCtr,a1,a2,a1a2Dist,dlam,bsDiam,detTyp
430//      Print xCtr,yCtr,a1,a2,a1a2Dist,dlam,bsDiam,detTyp
431       
432        realw[16]=xCtr          //xCtr(pixels)
433        realw[17]=yCtr  //yCtr (pixels)
434        realw[18]=sdd           //SDD (m)
435        realw[26]=lam           //wavelength (A)
436        //
437        // necessary values
438        realw[10]=5                     //detector calibration constants, needed for averaging
439        realw[11]=10000
440        realw[12]=0
441        realw[13]=5
442        realw[14]=10000
443        realw[15]=0
444        //
445        // used in the resolution calculation, ONLY here to keep the routine from crashing
446        realw[20]=65            //det size
447        realw[27]=dlam  //delta lambda
448        realw[21]=bsDiam        //BS size
449        realw[23]=a1            //A1
450        realw[24]=a2    //A2
451        realw[25]=a1a2Dist      //A1A2 distance
452        realw[4]=trans          //trans
453        realw[3]=0              //atten
454        realw[5]=thick          //thick
455        //
456        //
457        realw[0]=monCt          //def mon cts
458
459        // fake values to get valid deadtime and detector constants
460        //
461        textw[9]=detTyp+"  "            //6 characters 4+2 spaces
462        textw[3]="[NGxSANS00]"  //11 chars, NGx will return default values for atten trans, deadtime...
463       
464        //set the string values
465        formatStr="FILE: %s CREATED: %s"
466        sscanf hdr[0],formatStr,tempStr,junkStr
467
468        String/G $("root:"+destFolder+":fileList") = tempStr
469        textw[0] = tempStr              //filename
470        textw[1] = junkStr              //run date-time
471       
472        tempStr = hdr[1]
473        tempStr = tempStr[0,strlen(tempStr)-2]          //clean off the last LF
474
475        textW[6] = tempStr      //sample label
476       
477        return(0)
478End
479
480// read specific bits of information from the header
481// each of these operations MUST take care of open/close on their own
482
483// new, April 2011 for error propagation. fill these in with the facility-
484// specific versions, if desired.
485Function WriteTransmissionErrorToHeader(fname,transErr)
486        String fname
487        Variable transErr
488       
489
490        return(0)
491End
492
493Function WriteBoxCountsErrorToHeader(fname,rel_err)
494        String fname
495        Variable rel_err
496       
497        return(0)
498End
499
500Function getSampleTransError(fname)
501        String fname
502       
503        return(0)
504end
505
506Function getBoxCountsError(fname)
507        String fname
508       
509        return(0)
510end
511
512
513// end April 2011 additions
514
515
516Function/S getStringFromHeader(fname,wantedterm)
517        String fname, wantedterm                                //full path:name, term name
518       
519        String str = ""
520        Variable refNum,i
521       
522        //check the ext.
523        if (stringmatch(fname,"*.xml") <1)
524                //print "Failed: Not a *.xml file."
525                return (str)                            //Not *.xml. Do nothing...
526        endif
527        //actually open the file
528        refNum = XmlOpenFile(fname)     
529        if (refNum < 0)
530                //print "Failed: Not a xml file."
531                XmlCloseFile(refNum,0)
532                return (str)                            //Not a xml file. Do nothing...
533        endif
534
535        //ORNL HFIR SANS strings meta DATA
536        if (stringmatch("*filename",wantedterm)>0)
537                str =GetFName(fname,  1)
538        else
539                str=ReadSFromHHead(refNum,wantedterm)  //Get it from the header.
540       endif
541       
542        //return the data folder to root
543        //SetDataFolder root:
544               
545        return(str)
546End
547
548// file suffix (NCNR data file name specific)
549
550// file suffix (13 characters @ byte 19)
551Function/S getSuffix(fname)
552        String fname
553       
554        return(getStringFromHeader(fname,"//suffix"))           //!!!!!!!!!!!!!!!!!!!!!!!!!
555End
556
557// associated file suffix (for transmission)
558
559Function/S getAssociatedFileSuffix(fname)
560        String fname
561       
562        return(getStringFromHeader(fname,"//assoc_suffix"))             //!!!!!!!!!!!!!!!!!!!!!!!!!
563End
564
565// sample label (60 characters @ byte 98)
566Function/S getSampleLabel(fname)
567        String fname
568       
569        return(getStringFromHeader(fname,"//Header/Scan_Title"))
570End
571
572// file creation date (20 characters @ byte 55)
573Function/S getFileCreationDate(fname)
574        String fname
575 
576        return(getStringFromHeader(fname,"//SPICErack/@start_time"))
577End
578
579// Check if the file is transmission file?
580Function/S getIsTrans(fname)
581        String fname
582        return(getStringFromHeader(fname,"//Header/Transmission"))
583End
584
585// read a single real value with GBLoadWave
586Function getRealValueFromHeader(fname,wantedterm,unit)
587        String fname, wantedterm,unit
588       
589        Variable vresult
590        Variable refNum
591       
592        if (stringmatch(fname,"*.xml") <1)
593                //print "Failed: Not a *.xml file."
594                return 0                                //Not *.xml. Do nothing...
595        endif
596        //actually open the file
597        refNum = XmlOpenFile(fname)     
598        if (refNum < 0)
599                //print "Failed: Not a xml file."
600                return 0                                //Not a xml file. Do nothing...
601        endif
602
603        //ORNL HFIR SANS strings meta DATA
604       vresult=ReadVFromHHead(refNum,wantedterm,unit)
605       
606        return(vresult)
607End
608
609//monitor count is at byte 39
610Function getMonitorCount(fname)
611        String fname
612       
613        return(getRealValueFromHeader(fname,"//Counters/monitor",""))
614end
615
616//saved monitor count is at byte 43
617Function getSavMon(fname)
618        String fname
619       
620        return(getRealValueFromHeader(fname,"//Counters/monitor",""))  //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!??
621end
622
623//detector count is at byte 47
624Function getDetCount(fname)
625        String fname
626       
627        return(getRealValueFromHeader(fname,"//Counters/psd",""))   //Need to check!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
628end
629
630//Attenuator number is at byte 51
631Function getAttenNumber(fname)
632        String fname
633       
634        return(getRealValueFromHeader(fname,"//Motor_Positions/attenuation","percent")) //in unit of percents
635end
636
637//transmission is at byte 158
638Function getSampleTrans(fname)
639        String fname
640        return(getRealValueFromHeader(fname,"//Transmission_for_Sample",""))
641end
642
643//box counts are stored at byte 494
644Function getBoxCounts(fname)
645        String fname
646       
647        return(getRealValueFromHeader(fname,"//Box_Counts",""))                 
648end
649
650//whole detector trasmission is at byte 392
651Function getSampleTransWholeDetector(fname)
652        String fname
653       
654        return(getRealValueFromHeader(fname,"//Counters/detector","")) //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
655end
656
657//SampleThickness is at byte 162
658Function getSampleThickness(fname)
659        String fname
660       
661        return(getRealValueFromHeader(fname,"//Header/Sample_Thickness","cm"))
662end
663
664//Sample Rotation Angle is at byte 170
665Function getSampleRotationAngle(fname)
666        String fname
667       
668        return(getRealValueFromHeader(fname,"",""))                     //ToDo: define this...
669end
670
671//temperature is at byte 186
672Function getTemperature(fname)
673        String fname
674       
675        return(getRealValueFromHeader(fname,"//Parameter_Positions/tsample","C"))   
676end
677
678//field strength is at byte 190
679Function getFieldStrength(fname)
680        String fname
681       
682        return(getRealValueFromHeader(fname,"//magnetic_field","G"))
683end
684
685//beam xPos is at byte 252
686Function getBeamXPos(fname)
687        String fname
688       
689        return(getRealValueFromHeader(fname,"//Header/beam_center_x_pixel",""))
690end
691
692//beam Y pos is at byte 256
693Function getBeamYPos(fname)
694        String fname
695       
696        return(getRealValueFromHeader(fname,"//Header/beam_center_y_pixel",""))
697end
698
699//sample to detector distance is at byte 260
700Function getSDD(fname)
701        String fname
702       
703        return(getRealValueFromHeader(fname,"//Motor_Positions/sample_det_dist","m"))
704end
705
706//detector offset is at byte 264
707Function getDetectorOffset(fname)
708        String fname
709       
710        return(getRealValueFromHeader(fname,"//Motor_Positions/detector_trans","cm"))  //cm:  HFIR mm
711end
712
713//Beamstop diameter is at byte 272
714Function getBSDiameter(fname)
715        String fname
716       
717        return(getRealValueFromHeader(fname,"//Motor_Positions/beam_trap_size","mm"))  //check if this beamstop diameter?
718end
719
720//source aperture diameter is at byte 280
721Function getSourceApertureDiam(fname)
722        String fname
723       
724        return(getRealValueFromHeader(fname,"//Header/source_aperture_size","mm"))
725end
726
727//sample aperture diameter is at byte 284
728Function getSampleApertureDiam(fname)
729        String fname
730       
731        return(getRealValueFromHeader(fname,"//Header/sample_aperture_size","mm"))
732end
733
734//source AP to Sample AP distance is at byte 288
735Function getSourceToSampleDist(fname)
736        String fname
737       
738        return(getRealValueFromHeader(fname,"//Header/source_distance","m")) //unit=m   :hfir = mm
739end
740
741//wavelength is at byte 292
742Function getWavelength(fname)
743        String fname
744       
745        return(getRealValueFromHeader(fname,"//Header/wavelength", "A"))
746end
747
748//wavelength spread is at byte 296
749Function getWavelengthSpread(fname)
750        String fname
751       
752        return(getRealValueFromHeader(fname,"//Header/wavelength_spread",""))
753end
754
755//transmission detector count is at byte 388
756Function getTransDetectorCounts(fname)
757        String fname
758       
759        return(getRealValueFromHeader(fname,"//Counters/detector",""))   
760end
761
762//detector pixel X size is at byte 220
763Function getDetectorPixelXSize(fname)
764        String fname
765       
766        return(getRealValueFromHeader(fname,"//Header/x_mm_per_pixel","mm"))
767end
768
769//detector pixel Y size is at byte 232
770Function getDetectorPixelYSize(fname)
771        String fname
772       
773        return(getRealValueFromHeader(fname,"//Header/y_mm_per_pixel","mm"))
774end
775
776//total count time is at byte 31       
777Function getCountTime(fname)
778        String fname
779        Variable mtime
780       
781        mtime = getRealValueFromHeader(fname,"//Counters/time","")
782        if (mtime == 0)
783                mtime = 1               //get rid of a singular for calculating a rate in case.
784        endif
785        return(mtime)
786end
787
788
789// read the detector deadtime (in seconds)
790Function getDetectorDeadtime(fname)
791        String fname
792       
793        return(0)
794end
795
796
797//////  integer values
798//////Not used !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
799Function getIntegerFromHeader(fname,wanted)   ///Not used !!!!!!!!!
800        String fname                            //full path:name
801        String wanted           //starting byte
802
803        Variable refNum                                                               
804        Variable vresult
805       
806        if (stringmatch(fname,"*.xml") <1)
807                //print "Failed: Not a *.xml file."
808                return 0                                //Not *.xml. Do nothing...
809        endif
810        //actually open the file
811        refNum = XmlOpenFile(fname)
812        XMLclosefile(refNum, 0)
813        if (refNum < 0)
814                //print "Failed: Not a xml file."
815                return 0                                //Not a xml file. Do nothing...
816        endif
817
818        //ORNL HFIR SANS strings meta DATA
819       vresult=ReadVFromHHead(refNum,wanted, "")
820               
821        return(0)
822End
823//////////////////////////////////////////////////////////////////////////////////
824
825//reads the wavelength from a reduced data file (not very reliable)
826// - does not work with NSORTed files
827// - only used in FIT/RPA (which itself is almost NEVER used...)
828//
829Function GetLambdaFromReducedData(tempName)
830        String tempName
831       
832        String junkString
833        Variable lambdaFromFile, fileVar, junkVal
834        lambdaFromFile = 6.0
835
836        Open/R/P=catPathName fileVar as tempName
837        FReadLine fileVar, junkString
838        FReadLine fileVar, junkString
839        FReadLine fileVar, junkString
840        if(strsearch(LowerStr(junkString),"lambda",0) != -1)
841                FReadLine/N=11 fileVar, junkString
842                FReadLine/N=10 fileVar, junkString
843                sscanf  junkString, "%f",junkVal
844
845                lambdaFromFile = junkVal
846        endif
847        Close fileVar
848       
849        return(lambdaFromFile)
850End
851
852/////   TRANSMISSION RELATED FUNCTIONS    ////////
853//box coordinate are returned by reference
854//
855// box to sum over is bounded (x1,y1) to (x2,y2)
856//
857// this function returns the bounding coordinates as stored in
858// the header
859//
860// if not using the NCNR Transmission module, this function default to
861// returning 0000, and no changes needed
862Function getXYBoxFromFile(fname,x1,x2,y1,y2)
863        String fname
864        Variable &x1,&x2,&y1,&y2
865       
866        Variable refnum
867        String tmpFile = FindValidFilename(fname)
868        // tmpFile is only a parital path
869       
870        // return your bounding box coordinates or default values of 0
871        x1=getRealValueFromHeader(fname,"//XYBox_x1","")
872        x2=getRealValueFromHeader(fname,"//XYBox_x2","")
873        y1=getRealValueFromHeader(fname,"//XYBox_y1","")
874        y2=getRealValueFromHeader(fname,"//XYBox_y2","")
875       
876        if (x1 == -1 || x2 == -1 || y1 == -1 || y2 == -1)
877                x1 = 0
878                x2 = 0
879                y1 = 0
880                y2 = 0
881        endif
882       
883        return(0)
884End
885
886// Writes the coordinates of the box to the header after user input
887//
888// box to sum over bounded (x1,y1) to (x2,y2)
889//
890// if not using the NCNR Transmission module, this function is null
891Function WriteXYBoxToHeader(fname,x1,x2,y1,y2)
892        String fname
893        Variable x1,x2,y1,y2
894       
895        // your code to write bounding box to the header, or nothing
896        String x1str = "", x2str = "", y1str = "", y2str = ""
897        sprintf x1str, "%d", x1
898        sprintf x2str, "%d", x2
899        sprintf y1str, "%d", y1
900        sprintf y2str, "%d", y2
901
902        WriteHFIRHead(fname,x1str,"/SPICErack/XYBox_x1" ,"")   
903        WriteHFIRHead(fname,x2str,"/SPICErack/XYBox_x2" ,"")
904        WriteHFIRHead(fname,y1str,"/SPICErack/XYBox_y1" ,"")
905        WriteHFIRHead(fname,y2str,"/SPICErack/XYBox_y2" ,"")
906       
907        return(0)
908End
909
910// for transmission calculation, writes an NCNR-specific alphanumeric identifier
911// (suffix of the data file)
912//
913Function WriteAssocFileSuffixToHeader(fname,suffix)
914        String fname,suffix
915               
916       
917        WriteHFIRHead(fname,suffix,"/SPICErack/assoc_suffix" ,"text")
918        return(0)
919end
920
921
922//// ==================================================================
923//Keep these functions in case NIST changes: We need these...
924// TrimWhiteSpace (code from Jon Tischler)
925Function/T   HFIR_TrimWS(strg)
926   
927   String strg
928   return HFIR_TrimWSL(HFIR_TrimWSR(strg))
929End
930
931Function/T   HFIR_TrimWSL(strg)
932    String strg
933    Variable i, N=strlen(strg)
934    for (i=0;char2num(strg[i])<=32 && i<N;i+=1)    // find first non-white space
935    endfor
936    return strg[i,Inf]
937End
938
939Function/T   HFIR_TrimWSR(strg)
940    String strg
941    Variable i
942    for (i=strlen(strg)-1; char2num(strg[i])<=32 && i>=0; i-=1)    // find last non-white space
943   endfor
944    return strg[0,i]
945End
946//// ==================================================================
947
948Function ReadHFIRRaw(refNum,prtname,pname)   //NOT USED!!!!!!!!
949        Variable refNum
950        String pname, prtname
951       
952        //temp list of ns
953        MAKE/T/N=(1)/O nsList
954        nsList[0] = "1.1"
955       
956        // Check if  it is the SPICE version = 1.1
957        Variable  item,i
958        String thislocation, ns=""
959        Variable nns
960
961        for (item = 0; item < DimSize(nsList, 0); item += 1)            // loop over all possible namespaces
962                XMLlistAttr(refNum, prtname, nsList[item])
963                wave/T M_listAttr
964       
965                for (i = 0; i < DimSize(M_listAttr,0); i+=1)                    // loop over all available attributes
966                        // Expect the required hfir XML header (will fail if "schemalocation" is not found)
967                        if ( CmpStr(  LowerStr(M_listAttr[i][1]),  LowerStr(pname) ) == 0 )
968                                thisLocation = HFIR_TrimWS(M_listAttr[i][2])
969                                if ( StringMatch(thisLocation, nsList[item] + "*") )
970                                        ns = nsList[item]
971                                        Break
972                                endif
973                        endif
974                endfor
975                if (strlen(ns))
976                        Break           
977                endif
978        endfor
979        sscanf ns,"%f",nns
980return nns
981END
982
983
984////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
985//       Read ORNL HFIR SANS data ( xml format) file:general loading from display raw data
986////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
987Function ReadHFIRSansRaw(refNum,curFolder,tempheadhfir)
988    Variable refNum
989    String curFolder,tempheadhfir
990     
991        String curPath="root:Packages:NIST:"+curFolder
992        SetDataFolder curPath
993        Make/O/N=23 $(curPath+":IntegersRead")
994        Make/O/N=52 $(curPath+":RealsRead")
995        Make/O/T/N=11 $(curPath+":TextRead")
996       
997        Wave intw=$(curPath+":IntegersRead")
998        Wave realw=$(curPath+":RealsRead")
999        Wave/T textw=$(curPath+":TextRead")
1000       
1001        Variable ind,i,j,centerdata=1
1002        Variable pixnumx=0,pixnumy=0
1003        String val = "", pix_num = ""// numerical and text values
1004        Variable value = 0.0,t1=ticks
1005        String unitstr =""      //unit string
1006
1007        //Initialize wave values         
1008         realw=0
1009         intw=0
1010         textw=""
1011         textw[2]=curFolder
1012         textw[3]=""
1013         textw[4]="C"                                ///???
1014         textw[7]="C"                        // temperature unit C
1015         textw[10]="xml"                        //HFIR SANS RAW data file extension
1016         realw[4]  = 1                          //Default for transmission for sample
1017         realw[12]=0.00                       //following 6 values are for non-linear spatial corrections to a detector (RC timing)
1018         realw[15]=0.00                        // 10 and 13 are the X and Y pixel dimensions,,(11,12 and 13,14 are set to values for a linear response, as from a new Ordela detector)
1019         realw[11]=10000.00                          //nonlinear spatial pix(x) //Do not change unless knowing what you are doing...
1020         realw[14]=10000.00                          //nonlinear spatial pix(y)
1021         // detector physical width (right now assumes square...) (in cm)
1022         // beam stop X-position (motor reading, approximate cm from zero position)
1023         // currently NCNR-specific use to identify transmission measurements
1024         // you return 0
1025         realw[37] = 0
1026         //textw[2]="RAW"      //????
1027 
1028//      Print "Time to list attributes (s) = ",(ticks-t1)/60.15
1029//      Print "Time to list elements (s) = ",(ticks-t1)/60.15
1030
1031        // Get and set the number of pixels from the line just above data.
1032        pix_num = XMLstrFmXpath(refNum,"//Data/Detector/@type","","")
1033        pixnumx=Str2num(StringFromList(0,StringFromList(1,pix_num ,","),"]"))   
1034        pixnumy=Str2num(StringFromList(1,StringFromList(0,pix_num ,","),"["))
1035        Variable/G root:myGlobals:gNPixelsX=pixnumx
1036        Variable/G root:myGlobals:gNPixelsY=pixnumy     
1037        SetDataFolder curPath
1038
1039                        //******Below deleted since HFIR prefers to use <Data type="INT32[xxx,xxx]" for pixnumbers
1040                        //********Leave the following lines in case they change the policy.
1041                        //if (stringmatch(tempheadhfir,"Number_of_X_Pixels")>0)                 
1042                        //      pixnumx=Str2num(val)     
1043                        //      Variable/G root:myGlobals:gNPixelsX=pixnumx     
1044                        //       SetDataFolder curPath
1045                        //elseif  (stringmatch(tempheadhfir,"Number_of_Y_Pixels")>0)
1046                        //      pixnumy=Str2num(val)
1047                        //      Variable/G root:myGlobals:gNPixelsY=pixnumy
1048                        //       SetDataFolder curPath
1049                        // Note for units: If in-unit is null, out will be unity.
1050                        textw[6] = XMLstrFmXpath(refNum,"//Header/Scan_Title","","")
1051               
1052                        textw[3] = XMLstrFmXpath(refNum,"//Header/Users","","")         //ToDo: Define   
1053                               
1054                        textw[9] = XMLstrFmXpath(refNum,"//Header/Instrument","","")                            //ToDo: Define
1055                       
1056                        value = ValfromUnit(refNum,"//Transmission_for_Sample","")
1057                        if (value <= 0)
1058                                value = 1               //HFIR default = -1 while NIST package not working if it is <=0: Set default =1. <=NOT good!!!
1059                        endif
1060                        realw[4] = value
1061                       
1062                        realw[3] = ValfromUnit(refNum,"//Motor_Positions/attenuation","percent")
1063                        realw[8] = ValfromUnit(refNum,"//Parameter_Positions/tsample","C")
1064                        realw[0] = ValfromUnit(refNum,"//Counters/monitor","")
1065                        realw[5] = ValfromUnit(refNum,"//Header/Sample_Thickness","cm")
1066                        realw[2] = ValfromUnit(refNum,"//Counters/psd","")       ////Need to check!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1067                        realw[10] = ValfromUnit(refNum,"//Header/x_mm_per_pixel","mm") 
1068                        realw[13] = ValfromUnit(refNum,"//Header/y_mm_per_pixel","mm") 
1069                        Variable/G root:myGlobals:PixelResDefault = unit_convert(realw[13],"mm","cm") //back to cm unit for this default value??!!
1070                        SetDataFolder curPath
1071                       
1072                        realw[16] = ValfromUnit(refNum,"//Header/beam_center_x_pixel","") 
1073                        realw[17] = ValfromUnit(refNum,"//Header/beam_center_y_pixel","") 
1074                        realw[21] = ValfromUnit(refNum,"//Motor_Positions/beam_trap_size","mm")    //what is different from the beam trap diameter in the file???
1075                        realw[18] = ValfromUnit(refNum,"//Motor_Positions/sample_det_dist","m")
1076                        intw[1]  = ValfromUnit(refNum,"//Counters/time","sec")     //Not supported. Assumed in "sec"
1077                        intw[2] = intw[1] //???
1078                        realw[23]  = ValfromUnit(refNum,"//Header/source_aperture_size","mm")      //diameter???
1079                        realw[24]  = ValfromUnit(refNum,"//Header/sample_aperture_size","mm")      //diameter???
1080                        realw[25]  = ValfromUnit(refNum,"//Header/source_distance","m")         
1081                        realw[26]  = ValfromUnit(refNum,"//Header/wavelength","a")     
1082                        realw[27]  = ValfromUnit(refNum,"//Header/wavelength_spread","")       
1083                       
1084                        //Set pixel numbers
1085                        //SetDataFolder curPath
1086                        NVAR pixnumx1= root:myGlobals:gNPixelsX                     
1087                        NVAR pixnumy1= root:myGlobals:gNPixelsY
1088                        Variable pixnx = pixnumx1, pixny = pixnumy1
1089                        realw[20] = realw[10]*pixnx/10.0                        // physical detector width  in cm  // ToDo: Need to check for ypix size???
1090                       
1091                        //prepare to get data
1092                        Make/O/N=(pixnumx1*pixnumy1) $(curPath+":data")
1093                        WAVE  data=$(curPath+":data")
1094                        //set the globals to the detector dimensions (pixels)
1095                        Redimension/N=(pixnx,pixny) data                        //ORNL pixnums are given from the data file
1096                        Variable intens = 0
1097       
1098                        // Read 2d data
1099                        XMLwaveFmXpath(refNum,"/SPICErack/Data/Detector",""," \t\n\r")
1100                        WAVE/T M_xmlContent
1101                        for (i=0;i<pixnx;i+=1)
1102                                for  (j=0;j<pixny;j+=1)
1103                                        sscanf M_xmlContent[j+i*pixny],"%i", intens
1104                                        data[i][j]=intens
1105                                endfor
1106                        endfor
1107                       
1108
1109                       
1110                        ///////unit test 1/2//////////////////////////////////////////////////////////////////////////////////////////////////////////////
1111                        //if  (stringmatch(tempheadhfir,"Detector")<1 ||stringmatch(tempheadhfir,"data"))
1112                        //      print tempheadhfir+"="+val+"["+unitstr+"]"
1113                        //endif
1114                        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1115               
1116
1117
1118          //If the data is a sensitivity data, need to be narmalize so that the average over the detector should be 1.
1119         If (stringmatch(curFolder, "DIV") >0)
1120                //Variable V_avg
1121                 WaveStats/Z/Q data
1122                data /= V_avg
1123          endif
1124                       
1125
1126        //keep a string of the filename in the RAW folder
1127       
1128        Variable strpos
1129               
1130        textw[0] = RemoveAllSpaces(XMLstrFmXpath(refNum,"//SPICErack/@filename","","") )    //////ShortFileName(RemoveAllSpaces(XMLstrFmXpath(refNum,"//SPICErack/@filename","","") )  )         // file name
1131        textw[1] =   XMLstrFmXpath(refNum,"//SPICErack/@start_time","","")              //Date and Time
1132        textw[5]=StringFromList(0,textw[1]," ")                                                                         //Date
1133       
1134        //String/G $(curPath+":FileList") = textw[0]
1135       
1136        ///////unit test 2/2//////////////////////////////////////////////////////////////////////////////////////////////////////////////
1137        //SetDataFolder curPath
1138        //print "****** ["+num2str(pixnx)+","+num2str(pixny)+"]*******"
1139        //for (i=0;i<Dimsize(textw,0);i+=1)
1140        //      print "textw["+num2str(i)+"] ="+textw[i]
1141        //endfor
1142        //for (i=0;i<Dimsize(realw,0);i+=1)
1143        //      print "realw["+num2str(i)+"] ="+num2str(realw[i])
1144        //endfor
1145        //for (i=0;i<Dimsize(intw,0);i+=1)
1146        //      print "intw["+num2str(i)+"] ="+num2str(intw[i])
1147        //endfor
1148        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1149        // We have everything from file: Need to close the file soon as possible
1150        XMLclosefile(refNum, 0)
1151        SetDataFolder curPath
1152        Killwaves/Z M_listXPath
1153End
1154
1155/// Get real value in NIST unit ///////////////////////////////////////////////////////////////////////////////////////////////////
1156Function ValfromUnit(refNum,wantedterm,NISTunit)
1157        Variable refNum    //FileID
1158        String wantedterm,NISTunit  //Xpath, value in string, unit from HFIR, unit from NIST
1159       
1160        String val="", unitstr=""
1161        Variable value = 0.0
1162        //SetDataFolder curPath ////????????/
1163       
1164        val =   XMLstrFmXpath(refNum,wantedterm,"","")
1165
1166        // Case of no value or zero value, check if written by HFIR Patch
1167        if (stringmatch(wantedterm,"//*")>0&& strlen(val) ==0)
1168                 wantedterm = "//" +  StringFromList(3, wantedterm,"//")
1169                 // if valid wnatedterm
1170                 if (strlen(wantedterm) >1)
1171                        val =   XMLstrFmXpath(refNum,wantedterm,"","")
1172                 endif
1173        endif   
1174        unitstr =  RemoveAllSpaces(XMLstrFmXpath(refNum,wantedterm+"/@units","",""))
1175       
1176        //The units of the source_distance is treated special...
1177        if (stringmatch(wantedterm,"*source_distance")>0 )
1178                if  (strlen(unitstr)==0)
1179                        unitstr = "mm"          //Give mm unit since no unit is provided from the file. ///This needs to be corrected soon!!!!
1180                 endif
1181        endif
1182        //String to double
1183        sscanf val, "%f", value
1184        Variable data
1185        data = unit_convert(value,unitstr,NISTunit)
1186
1187        return data
1188End
1189
1190
1191//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1192//Read Real Values from HFIR data 
1193//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1194Function ReadVFromHHead(refNum,wantedterm,NCunit)
1195      Variable refNum
1196      String wantedterm, NCunit
1197     
1198      Variable vresult=-1  // (wantedterm=="", return -1)
1199        Variable ind=0,i=0, value = 0
1200        String  ntype = ""
1201        String savedDataFolder = GetDataFolder(1)
1202        //Default for transmission rate (between 0 to 1): HFIR not provide this as a Float number???? ==>make one: if exist, read it below.
1203        if (stringmatch(wantedterm,"//Transmission_for_Sample")>0)
1204                vresult=1               
1205        endif
1206       
1207        String unitstr = "", typestr="",tempheadhfir="", val=""
1208
1209        if (stringmatch(wantedterm,"") >0 ) // set zero if wnatedterm is "" ,not defined(eg., rotation angle).
1210                vresult =0
1211                //close here
1212                XMLclosefile(refNum, 0)
1213                return vresult
1214        else
1215                //Find the value,unit, and type of the value: a little ugly but faster...
1216                val =   XMLstrFmXpath(refNum,wantedterm,"","")
1217                // Case of no value or zero value, check if it written by HFIR Patch
1218                if (stringmatch(wantedterm,"//*")>0&& strlen(val) ==0)
1219                        wantedterm = "//" +  StringFromList(3, wantedterm,"//")
1220                        // if valid wnatedterm
1221                        if (strlen(wantedterm) >1)
1222                                val =   XMLstrFmXpath(refNum,wantedterm,"","")
1223                        endif
1224                endif
1225                unitstr =  RemoveAllSpaces(XMLstrFmXpath(refNum,wantedterm+"/@units","",""))
1226                typestr =  RemoveAllSpaces(XMLstrFmXpath(refNum,wantedterm+"/@type","",""))
1227                //close here
1228                XMLclosefile(refNum, 0)
1229        endif
1230       
1231        if   (stringmatch(typestr , "INT*")>0)
1232                ntype = "i"             //INT32
1233        elseif (stringmatch(typestr , "FLOAT*")>0)
1234                ntype ="f"              //FLOAT32
1235        else
1236                ntype ="s"              //TEXT
1237        endif   
1238       
1239        String ustr ="%f"                               //default: float
1240        if (stringmatch(ntype,"i") > 0) //for integer   
1241                ustr = "%d"
1242        endif   
1243                                       
1244        //Special case starts!!!
1245        //No unit found in hfir ("mm") but needs to convert to meters.
1246        //The following 3 lines should be removed once HFIR puts th units on the raw data files.
1247        if (stringmatch(wantedterm,"*source_distance")>0&& strlen(unitstr) ==0)
1248                unitstr = "mm"         
1249        endif
1250        //Special case ends!!!
1251       
1252        //Do NOT use str2num(): will loose many decimal digits.
1253        sscanf val, ustr, value
1254        vresult = unit_convert(value,unitstr,NCunit)
1255        if (stringmatch(wantedterm,"*Transmission_for_Sample")>0 && vresult == 0)
1256                 //Transmission default value if it was set to 0.
1257                 vresult = 1
1258        endif
1259                       
1260        //Set PixResDefault from y_mm_per_pixel (not x_mm_per_pixel!!!!!!!!)
1261        if (stringmatch(wantedterm,"*y_mm_per_pixel")>0)
1262                 Variable/G root:myGlobals:PixelResDefault = unit_convert(vresult,"mm","cm") //back to cm unit for this default value??!!
1263                 SetDataFolder savedDataFolder          //In case...
1264        endif
1265
1266               
1267        return (vresult)
1268
1269End
1270
1271/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1272//Read Strings from HFIR data 
1273/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1274Function/S ReadSFromHHead(refNum,wantedterm)
1275      Variable refNum
1276      String wantedterm
1277     
1278      String tempheadhfir = ""
1279      String result = "",gotterm ="n" ,name
1280        Variable ind,i
1281
1282      if   (stringmatch(wantedterm,"")>0)
1283                result = ""
1284                XMLclosefile(refNum, 0)
1285                return (result)
1286        endif
1287       
1288        result =  XMLstrFmXpath(refNum,wantedterm,"","")
1289        if (stringmatch(result, "") != -1 )     
1290                gotterm ="y"   
1291        endif
1292
1293        //HFIR header does not have "suffix" tag but one can get the info from file name before user writes the tag into the header.
1294        if (stringmatch("",result)>0     && stringmatch("//suffix",wantedterm)>0 )
1295                name = RemoveAllSpaces(XMLstrFmXpath(refNum,"//SPICErack/@filename","",""))
1296                result=StringFromList(2,StringFromList(0, name,"."), "_")+"_"+StringFromList(3,StringFromList(0,name,"."), "_")
1297        endif
1298
1299        //Close file here.
1300        XMLclosefile(refNum, 0)
1301       
1302        if (stringmatch(gotterm,"n")>0 )
1303                result = ""
1304        endif   
1305
1306      return (result)
1307End
1308
1309
1310//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1311//WRITE Real Values to HFIR data file 
1312//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1313
1314Function WriteHFIRHead(filename,value,wantedterm,NCunit)
1315     
1316      String filename, value,wantedterm, NCunit //where value is a string...
1317     
1318        String valstr
1319      Variable/D vresult = 0
1320      Variable refNum
1321        Variable ind=0,i=0, vals
1322       
1323        Variable typenum = 0
1324        String ntype = ""       //Do not change this initial, "".
1325        String nstr = "/SPICErack"              //to add new nodes and content: NEVER CAHNGE this string
1326        String errorMsg =""
1327       
1328        //print "Loading", filename, "..."
1329        if (stringmatch(filename,"*.xml") <1)
1330                //print "\r  ==>  Failed: Not a *.xml file."
1331                return 0                                //Not *.xml. Do nothing...
1332        endif
1333        //actually open the file
1334        refNum = XmlOpenFile(filename) 
1335
1336        if (refNum < 0)
1337                switch(refNum)                                 
1338                        case -1:
1339                                errorMsg = errorMsg+filename+ "  ==>  Not a standard xml file format; Please check if the file is not broken..."
1340                        break
1341                        case -2:
1342                                errorMsg = errorMsg+filename+"  ==>  Please check if the file name is same as that written in the header..."
1343                        break
1344                endswitch
1345                print errorMsg
1346                XMLclosefile(refNum, 0)
1347                return -1                               //Not a xml file. Do nothing...
1348        endif
1349
1350                String unitstr = "",typestr="", val=""
1351
1352                if  (strlen(wantedterm)==0)     
1353                        vresult =0                              //If input is NULL, do nothing...
1354                        nstr = ""                                       //reset as No new node
1355
1356                else   //(stringmatch(tempheadhfir,wantedterm)>0)       
1357                        val =   XMLstrFmXpath(refNum,wantedterm,"","")
1358                        // if no regular entry is found, check patch entry.
1359                        if (stringmatch(wantedterm,"//*")>0&& strlen(val) ==0)
1360                                wantedterm = "//" +  StringFromList(3, wantedterm,"//")
1361                                // if valid wnatedterm
1362                                if (strlen(wantedterm) >1)
1363                                        val =   XMLstrFmXpath(refNum,wantedterm,"","")
1364                                endif
1365                        endif
1366                        //Special case starts!!!
1367                        //No unit founds in hfir ("mm") file but needs to convert to meters. Let's give it one.
1368                        if (stringmatch(wantedterm,"*source_distance")>0&& strlen(unitstr) ==0)
1369                                unitstr = "mm" 
1370                                ntype ="f"     
1371                        //Special case ends!!!
1372                        else
1373                                unitstr =  XMLstrFmXpath(refNum,wantedterm+"/@units","","")
1374                                typestr =  RemoveAllSpaces(XMLstrFmXpath(refNum,wantedterm+"/@type","",""))
1375       
1376                                ntype ="s"              //TEXT 
1377                               
1378                                        if  (strlen(typestr)==0)
1379                                                ntype = "s"
1380                                        elseif   (stringmatch(typestr, "INT*")>0)
1381                                                ntype = "i"             //INT32
1382                                        elseif (stringmatch(typestr, "FLOAT*")>0)
1383                                                ntype ="f"              //FLOAT32
1384                                        endif   
1385                        endif
1386                       
1387                        if (stringmatch(ntype,"s") > 0) //for strings           
1388                                vresult = 1                     
1389                                valstr =value
1390                        else
1391                                String ustr ="%f"                               //default: float
1392                                if (stringmatch(ntype,"i") > 0) //for integer   
1393                                        ustr = "%d"
1394                                endif                   
1395                                sscanf  value,ustr, vals
1396                                vresult = unit_convert(vals,NCunit,unitstr)     //Unit correction...(back to the HFIR unit)
1397                               
1398                                sprintf valstr,ustr, vresult
1399                        endif
1400                       
1401                        if (stringmatch(wantedterm,"/SPICErack/*")>0&& strlen(val) ==0)
1402                                nstr = "/SPICErack"
1403                                // remove "/SPICErack/" from wantedterm
1404                                wantedterm = StringFromList(2, wantedterm,"/SPICErack/")
1405                        elseif (stringmatch(wantedterm,"//*")>0&& strlen(val) ==0)
1406                                nstr = "/SPICErack"
1407                                //remove'//' to wantedterm
1408                                wantedterm = StringFromList(2, wantedterm,"//")
1409                        else
1410                                XMLsetNodeStr(refNum,wantedterm,"",valstr)      //to set
1411                                nstr = ""                               //reset as No new node
1412                        endif
1413                        //break
1414                 endif         
1415        //to write new  attr name and value which are not found in the raw file.
1416        if (strlen(nstr)>2)                             
1417                 XMLaddNode(refNum,nstr,"",wantedterm,value,1)
1418                 // nstr to add new node
1419                 nstr = "//"+wantedterm
1420                 // get unit
1421                 if (stringmatch(NCunit,"text")>0)     
1422                        ntype = "text"
1423                        vresult = 1
1424                 else
1425                        XMLsetAttr(refNum,nstr,"","units",NCunit)       //use NIST units.
1426                        ntype = "FLOAT32"                                               //Let's set the any number as float for now... 
1427                        sscanf  value, "%f", vals
1428                        vresult = vals         
1429                 endif
1430                 //print "*** Note:*** \r     *** No parameter named",wantedterm, "was found, so it was added to the end of your data file."
1431                 XMLsetAttr(refNum,nstr,"","type",ntype)       
1432        endif
1433
1434        //KillWaves/Z W_ElementList,M_xmlContent,M_listXPath,M_listAttr                 //clean up
1435        if      (strlen(wantedterm)==0 && vresult == -1)
1436                XMLclosefile(refNum, 0)
1437                //print "Failed writing",wantedterm, "on", filename, "..."
1438        else
1439                XMLclosefile(refNum, 1)                                         //save and close the file.
1440                //print "Finished writing",wantedterm,"=",value,"[",NCunit,"]  on", filename, "..."
1441        endif
1442        return (vresult)
1443
1444End
1445
1446
1447Function UserGetWLPanel_ContButton(cntrlName)
1448      String cntrlName
1449      DoWindow /K WaveLengthInput
1450End
1451
1452Function Daskcheckbox(cntrlName,checked)
1453String cntrlName
1454Variable checked
1455
1456Wave realw=$"root:RAW:RealsRead"
1457Variable/G root:myGlobals:globDask=checked
1458      if (checked==1)
1459           Variable /G root:myGlobals:globwlfix=realw[26]
1460           Variable /G root:myGlobals:globdwlfix=realw[27]
1461      endif
1462
1463 End
1464 
1465 
1466Function Daskcheckbox1(cntrlName,checked)
1467String cntrlName
1468Variable checked
1469
1470Wave templw=$"root:RAW:tempwave1"
1471Variable/G root:myGlobals:globDask1=checked
1472      if (checked==1)
1473           Variable /G root:myGlobals:globwlfix=templw[0]
1474           Variable /G root:myGlobals:globdwlfix=templw[1]
1475      endif
1476
1477 End
1478 
1479//Write whether Transmission is True or False.
1480Function Write_isTransmissionToHeader(fname,str)
1481        String fname,str
1482
1483        WriteHFIRHead(fname,str, "//Header/Transmission","text")       
1484        return(0)
1485End
1486
1487//sample transmission is a real value at byte 158
1488Function WriteTransmissionToHeader(fname,trans)
1489        String fname
1490        Variable trans
1491
1492        String transstr = ""
1493        sprintf transstr, "%f", trans
1494
1495         WriteHFIRHead(fname,transstr,"/SPICErack/Transmission_for_Sample" ,"")                 
1496        return(0)
1497End
1498
1499//whole transmission is a real value at byte 392
1500Function WriteWholeTransToHeader(fname,trans)
1501        String fname
1502        Variable trans
1503
1504        String transstr = ""
1505        sprintf transstr, "%f", trans
1506
1507        WriteHFIRHead(fname,transstr,"//Counters/detector" ,"")         //????????????????????????????????????????????????????????
1508        return(0)
1509End
1510
1511//box sum counts is a real value
1512// used for transmission calculation module
1513//box sum counts is a real value at byte 494
1514Function WriteBoxCountsToHeader(fname,counts)
1515        String fname
1516        Variable counts
1517
1518        String countsstr = ""
1519        sprintf countsstr, "%f", counts
1520
1521        WriteHFIRHead(fname,countsstr,"/SPICErack/Box_Counts" ,"")     
1522        return(0)
1523End
1524
1525//Below units refer to NIST units..
1526//beam stop X-pos is at byte 368
1527Function WriteBSXPosToHeader(fname,xpos)
1528        String fname
1529        Variable xpos
1530
1531        String xposstr = ""
1532        sprintf xposstr, "%f", xpos
1533
1534        WriteHFIRHead(fname,xposstr,"//Motor_Positions/beam_trap_x","mm")       ///Is this diameter?
1535        return(0)
1536End
1537
1538//sample thickness is at byte 162
1539Function WriteThicknessToHeader(fname,num)
1540        String fname
1541        Variable num
1542
1543        String numstr = ""
1544        sprintf numstr, "%f", num
1545
1546        WriteHFIRHead(fname,numstr,"//Header/Sample_Thickness","cm")
1547        return(0)
1548End
1549
1550//beam center X pixel location is at byte 252
1551Function WriteBeamCenterXToHeader(fname,num)
1552        String fname
1553        Variable num
1554
1555        String numstr = ""
1556        sprintf numstr, "%f", num
1557
1558        WriteHFIRHead(fname,numstr,"//Header/beam_center_x_pixel" ,"")
1559        return(0)
1560End
1561
1562//beam center Y pixel location is at byte 256
1563Function WriteBeamCenterYToHeader(fname,num)
1564        String fname
1565        Variable num
1566
1567        String numstr = ""
1568        sprintf numstr, "%f", num
1569
1570        WriteHFIRHead(fname,numstr,"//Header/beam_center_y_pixel","")
1571        return(0)
1572End
1573
1574//Attenuation (percent) 0 for no attanuation (not its transmission)
1575Function WriteAttenNumberToHeader(fname,num)
1576        String fname
1577        Variable num
1578
1579        String numstr = ""
1580        sprintf numstr, "%f", num
1581
1582        WriteHFIRHead(fname,numstr,"//Motor_Positions/attenuation","percent")   // HFIR has attenuation % instead of this. thus user has to use patch unless somebody change the format!!!!
1583        return(0)
1584End
1585
1586//monitor count is at byte 39
1587Function WriteMonitorCountToHeader(fname,num)
1588        String fname
1589        Variable num
1590
1591        String numstr = ""
1592        sprintf numstr, "%f", num
1593
1594        WriteHFIRHead(fname,numstr,"//Counters/monitor","")
1595        return(0)
1596End
1597
1598//total detector count is at byte 47
1599Function WriteDetectorCountToHeader(fname,num)
1600        String fname
1601        Variable num
1602
1603        String numstr = ""
1604        sprintf numstr, "%f", num
1605
1606        WriteHFIRHead(fname,numstr,"//Counters/psd","")
1607        return(0)
1608End
1609
1610//transmission detector count is at byte 388
1611Function WriteTransDetCountToHeader(fname,num)
1612        String fname
1613        Variable num
1614
1615        String numstr = ""
1616        sprintf numstr, "%f", num
1617
1618        WriteHFIRHead(fname,numstr,"//Counters/detector","")   ///Check with Steve & Ken!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1619        return(0)
1620End
1621
1622//wavelength is at byte 292
1623Function WriteWavelengthToHeader(fname,num)
1624        String fname
1625        Variable num
1626
1627        String numstr = ""
1628        sprintf numstr, "%f", num
1629
1630        WriteHFIRHead(fname,numstr,"//Header/wavelength" ,"angstroms")
1631        return(0)
1632End
1633
1634//wavelength spread is at byte 296
1635Function WriteWavelengthDistrToHeader(fname,num)
1636        String fname
1637        Variable num
1638
1639        String numstr = ""
1640        sprintf numstr, "%f", num
1641
1642        WriteHFIRHead(fname,numstr,"//Header/wavelength_spread","")
1643        return(0)
1644End
1645
1646//temperature is at byte 186
1647Function WriteTemperatureToHeader(fname,num)
1648        String fname
1649        Variable num
1650
1651        String numstr = ""
1652        sprintf numstr, "%f", num
1653
1654        WriteHFIRHead(fname,numstr,"//Parameter_Positions/tsample" ,"C")
1655        return(0)
1656End
1657
1658//magnetic field is at byte 190
1659Function WriteMagnFieldToHeader(fname,num)
1660        String fname
1661        Variable num
1662
1663        String numstr = ""
1664        sprintf numstr, "%f", num
1665
1666        WriteHFIRHead(fname,numstr,"/SPICErack/magnetic_field","G")  //Not defined on HFIR file...  Should be changed the name when decided...
1667        return(0)
1668End
1669
1670//Source Aperture diameter is at byte 280
1671Function WriteSourceApDiamToHeader(fname,num)
1672        String fname
1673        Variable num
1674
1675        String numstr = ""
1676        sprintf numstr, "%f", num
1677
1678        WriteHFIRHead(fname,numstr,"//Header/source_aperture_size","mm")
1679        return(0)
1680End
1681
1682//Sample Aperture diameter is at byte 284
1683Function WriteSampleApDiamToHeader(fname,num)
1684        String fname
1685        Variable num
1686
1687        String numstr = ""
1688        sprintf numstr, "%f", num
1689
1690        WriteHFIRHead(fname,numstr,"//Header/sample_aperture_size","mm")
1691        return(0)
1692End
1693
1694//Source to sample distance is at byte 288
1695Function WriteSrcToSamDistToHeader(fname,num)
1696        String fname
1697        Variable num
1698
1699        String numstr = ""
1700        sprintf numstr, "%f", num
1701
1702        WriteHFIRHead(fname,numstr,"//Header/source_distance","m")     //unit=m   :hfir = mm ???????????????
1703        return(0)
1704End
1705
1706//detector offset is at byte 264
1707Function WriteDetectorOffsetToHeader(fname,num)
1708        String fname
1709        Variable num
1710
1711        String numstr = ""
1712        sprintf numstr, "%f", num
1713
1714        WriteHFIRHead(fname,numstr,"//Header/detector_trans","cm")  //cm:  HFIR = mm !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1715        return(0)
1716End
1717
1718//beam stop diameter is at byte 272
1719Function WriteBeamStopDiamToHeader(fname,num)
1720        String fname
1721        Variable num
1722       
1723        String numstr = ""
1724        sprintf numstr, "%f", num
1725       
1726        WriteHFIRHead(fname,numstr,"//Motor_Positions/beam_trap_size","mm")  //check !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1727        return(0)
1728End
1729
1730//sample to detector distance is at byte 260
1731Function WriteSDDToHeader(fname,num)
1732        String fname
1733        Variable num
1734
1735        String numstr = ""
1736        sprintf numstr, "%f", num
1737       
1738        WriteHFIRHead(fname,numstr,"//Motor_Positions/sample_det_dist","m")
1739        return(0)
1740End
1741
1742//detector pixel X size (mm) is at byte 220
1743Function WriteDetPixelXToHeader(fname,num)
1744        String fname
1745        Variable num
1746
1747        String numstr = ""
1748        sprintf numstr, "%f", num
1749       
1750        WriteHFIRHead(fname,numstr, "//Header/x_mm_per_pixel","mm")
1751        return(0)
1752End
1753
1754//detector pixel Y size (mm) is at byte 232
1755Function WriteDetPixelYToHeader(fname,num)
1756        String fname
1757        Variable num
1758       
1759        String numstr = ""
1760        sprintf numstr, "%f", num
1761       
1762        WriteHFIRHead(fname,numstr, "//Header/y_mm_per_pixel","mm")
1763        return(0)
1764End
1765
1766// Write the detector deadtime to the file header (in seconds)
1767Function WriteDeadtimeToHeader(fname,num)
1768        String fname
1769        Variable num
1770       
1771        return(0)
1772End
1773
1774// sample label
1775// limit to 60 characters
1776Function WriteSamLabelToHeader(fname,str)
1777        String fname,str
1778       
1779        if(strlen(str) > 60)
1780                str = str[0,59]
1781        endif
1782        WriteHFIRHead(fname,str, "//Header/Scan_Title","text") //Users tend to put the sample descrpt here instead of "Sample_Name"...
1783        return(0)
1784End
1785
1786
1787Function WriteCountTimeToHeader(fname,num)
1788        String fname
1789        Variable num
1790       
1791        String numstr = ""
1792        sprintf numstr, "%f", num
1793       
1794        WriteHFIRHead(fname,numstr,"//Counters/time","sec")
1795        return(0)
1796End
1797
1798
1799/////Handy Unit converter for length & time units"
1800Function length_unit_convert(from,to)  // input: ("m", cm")==> output=10,....;   input: ("", "") ==> out = 1
1801        String from, to
1802       
1803        Variable i, out
1804       
1805        Make/O/T/N=(18,2) munit
1806       
1807        //ToDo: to combine the same units       
1808        //length units
1809        munit[0][0]="m"   //popular units first...
1810        munit[0][1]= "1"
1811        munit[1][0]="cm"
1812        munit[1][1]= "0.01"
1813        munit[2][0]="mm"
1814        munit[2][1]= "0.001"
1815        munit[3][0]="angstroms"  //HFIR used this rather than A
1816        munit[3][1]= "1e-10"
1817        munit[4][0]="meters"
1818        munit[4][1]= "1"
1819        munit[5][0]="um"
1820        munit[5][1]= "1e-06"
1821        munit[6][0]="nm"
1822        munit[6][1]= "1e-09"
1823        munit[7][0]="km"
1824        munit[7][1]= "1000"
1825        munit[8][0]="a"
1826        munit[8][1]= "1e-10"
1827        munit[9][0]="angstrom"
1828        munit[9][1]= "1e-10"
1829        munit[10][0]="microns"
1830        munit[10][1]= "1e-6"
1831        munit[11][0]="meter"
1832        munit[11][1]= "1"
1833       
1834        //time units
1835        munit[12][0]="sec"
1836        munit[12][1]= "1"
1837        munit[13][0]="seconds"
1838        munit[13][1]= "1"
1839        munit[14][0]="min"
1840        munit[14][1]= "60"
1841        munit[15][0]="minutes"
1842        munit[15][1]= "60"
1843        munit[16][0]="hrs"
1844        munit[16][1]= "3600"
1845        munit[17][0]="hours"
1846        munit[17][1]= "3600"
1847        //Add more units here...
1848         
1849        String  v_from="", v_to=""
1850        for (i = 0; i<DimSize(munit,0); i+=1)
1851                if (stringmatch(munit[i][0],from)>0)  // IgorPro "stringmatch()" function handles both lower & upper cases.
1852                        v_from = munit[i][1]
1853                        break
1854                endif
1855        endfor
1856       
1857        for (i = 0; i<DimSize(munit,0); i+=1)
1858                if (stringmatch(munit[i][0],to)>0)
1859                        v_to = munit[i][1]
1860                        break
1861                endif
1862        endfor
1863       
1864        KillWaves/Z munit
1865       
1866       
1867        if (strlen(v_from)==0 || strlen(v_to) ==0)
1868                out = 1                 //Do nothing...
1869        else
1870                Variable vf, vt
1871                sscanf  v_to, "%f", vt
1872                sscanf  v_from, "%f", vf
1873                out = vf / vt
1874        endif
1875        return out
1876End
1877
1878
1879///For length and temperature units
1880Function unit_convert(val, from,to)  // input: ("m", cm")==> output=10,....;   input: ("", "") ==> out = 1
1881        Variable val
1882        String from, to
1883
1884        from = RemoveAllSpaces(from)
1885        to = RemoveAllSpaces(to)
1886                       
1887        Variable i, out = val
1888
1889        //Search for two same strings, or one with none.
1890        if (stringmatch(from,to)>0 ||strlen(from) == 0||strlen(to)==0)
1891                out = val
1892               
1893        //Temperature unit: support only C and K
1894        elseif (stringmatch(from,"C")>0 || stringmatch(to,"K")>0||stringmatch(to,"C")>0 || stringmatch(from,"K")>0)
1895                out =temp_unit_convert(val, from,to)
1896               
1897        //Length unit                   
1898        else
1899                out = val*length_unit_convert(from,to)                                                 
1900        endif
1901
1902        return out
1903End
1904
1905//temperature unit converter: Only support K and C.
1906Function temp_unit_convert(val, from,to) 
1907        Variable val
1908        String from, to
1909       
1910        Variable i, j, out = val
1911
1912        Make/O/T/N=(2,2) tunit
1913       
1914        tunit[0][0]="C"   //popular units first...
1915        tunit[0][1]= "-273.15"
1916        tunit[1][0]="K"
1917        tunit[1][1]= "0"       
1918
1919        String  v_from="", v_to=""
1920
1921        for (i = 0; i<DimSize(tunit,0); i+=1)
1922                if (stringmatch(tunit[i][0],from)==1)  // IgorPro "stringmatch()" function handles both lower & upper cases.
1923                        v_from = tunit[i][1]
1924                        break
1925                endif
1926        endfor
1927
1928        for (j = 0; j<DimSize(tunit,0); j+=1)
1929                if (stringmatch(tunit[j][0],to)==1)
1930                        v_to = tunit[j][1]
1931                        break
1932                endif   
1933        endfor 
1934        KillWaves/Z tunit
1935        if (strlen(v_from)==0 || strlen(v_to) ==0)
1936                out = 1                 //Do nothing...
1937        else
1938                Variable vt, vf
1939                sscanf  v_to, "%f", vt
1940                sscanf  v_from, "%f", vf
1941                out = val + (vt - vf)
1942        endif
1943        return out
1944End
1945
1946
1947///This function make HFIR SANS data file shorter which is more than 30 characters causing problem taking other names after the file name.
1948//Will remove instrumental name.
1949Function/S ShortFileName(fileName)
1950        String fileName
1951        //Default: just passing
1952        String fname = fileName
1953
1954        //Check whether it is from HiResSANS or BioSANS and remove the head
1955        if (stringmatch(fileName,"HiResSANS_*.*")>0 )
1956                fname = ReplaceString("HiResSANS_",fname,"HS_",0,1)   
1957        elseif (stringmatch(filename,"BioSANS_*.*")>0)
1958                fname = ReplaceString("BioSANS_",fname,"BS_",0,1)     
1959        endif
1960        return fname
1961END
1962
1963//Not used
1964///This function return the original HFIR SANS data file name that was shorten before.
1965//Put them back to HiResSANS*** or BioSANS***.
1966Function/S FullFileName(fname)
1967        String fname
1968        //Default: just passing
1969        String fileName = fname
1970       
1971        //Check whether it is from HiResSANS or BioSANS
1972        if (stringmatch(fname,"*HS_*.*")>0 )
1973                fileName = ReplaceString("HS_",fname,"HiResSANS_",0,1) 
1974        elseif (stringmatch(fname,"*BS_*.*")>0)
1975                fileName = ReplaceString("BS_",fname,"BioSANS_",0,1)   
1976        endif
1977
1978        return fileName
1979END
1980
1981
1982///Find file name from full Path+file
1983Function/S GetFName(path,  length)
1984        String path
1985        Variable length // 1 for full name, 0 for shorten name, others pass the name
1986       
1987        Variable index
1988        String ofname, mfname
1989       
1990        // get index of the file name
1991        index = ItemsInList(path,":") - 1
1992        // get file name
1993        ofname = StringFromList(index,path,":")
1994        //modify the name if need otherwise return w/o change
1995        if (length == 0)
1996                mfname = ShortFileName(ofname)
1997        elseif (length == 1)
1998                mfname = FullFileName(ofname)
1999        else
2000                mfname = ofname
2001        endif
2002        // return the path+modified file name
2003        return mfname
2004End
2005
2006
2007///Find file name from full Path+file and replace file name to a shorter or full name in path+file.
2008Function/S ReplaceFName(path,  length)
2009        String path
2010        Variable length // 1 for full name, 0 for shorten name
2011       
2012        Variable index
2013        String ofname,mfname
2014       
2015        // get index of the file name
2016        index = ItemsInList(path,":") - 1
2017        // get file name
2018        ofname = StringFromList(index,path,":")
2019        //modify the name if need otherwise return w/o change
2020        if (length == 0)
2021                mfname = ShortFileName(ofname)
2022        else
2023                mfname = FullFileName(ofname)
2024        endif
2025        // return the path+modified file name
2026        return ReplaceString(ofname,path,mfname,0,1)
2027End
2028
2029////Unused ///Not working well
2030// Change file name before and after Xml open
2031Function/S XmlFileOpen(fname)
2032        String fname
2033       
2034        // fname = path + full file name
2035        fname = ReplaceFName(fname,  1)
2036        XmlOpenFile(fname)
2037        // path + short file name
2038        return ReplaceFName(fname,  0)
2039End
2040
2041
2042////// OCT 2009, facility specific bits from ProDiv()
2043//"type" is the data folder that has the corrected, patched, and normalized DIV data array
2044//
2045// the header of this file is rather unimportant. Filling in a title at least would be helpful/
2046//
2047Function Write_DIV_File(type)
2048        String type
2049       
2050        // Your file writing function here. Don't try to duplicate the VAX binary format...
2051       
2052        return(0)
2053End
2054
2055////// OCT 2009, facility specific bits from MonteCarlo functions()
2056//"type" is the data folder that has the data array that is to be (re)written as a full
2057// data file, as if it was a raw data file
2058//
2059// not really necessary
2060//
2061Function Write_RawData_File(type,fullpath,dialog)
2062        String type,fullpath
2063        Variable dialog         //=1 will present dialog for name
2064       
2065        // Your file writing function here. Don't try to duplicate the VAX binary format...
2066        Print "Write_RawData_File stub"
2067       
2068        return(0)
2069End
Note: See TracBrowser for help on using the repository browser.