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

Last change on this file since 804 was 804, checked in by srkline, 12 years ago

Fixes in HFIR_DataReadWrite (JaeHie? Cho). Now the reader it writes back if attr. entry does not exist in the data file.

File size: 59.3 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//////  integer values
789//////Not used !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
790Function getIntegerFromHeader(fname,wanted)   ///Not used !!!!!!!!!
791        String fname                            //full path:name
792        String wanted           //starting byte
793
794        Variable refNum                                                               
795        Variable vresult
796       
797        if (stringmatch(fname,"*.xml") <1)
798                //print "Failed: Not a *.xml file."
799                return 0                                //Not *.xml. Do nothing...
800        endif
801        //actually open the file
802        refNum = XmlOpenFile(fname)
803        XMLclosefile(refNum, 0)
804        if (refNum < 0)
805                //print "Failed: Not a xml file."
806                return 0                                //Not a xml file. Do nothing...
807        endif
808
809        //ORNL HFIR SANS strings meta DATA
810       vresult=ReadVFromHHead(refNum,wanted, "")
811               
812        return(0)
813End
814//////////////////////////////////////////////////////////////////////////////////
815
816//reads the wavelength from a reduced data file (not very reliable)
817// - does not work with NSORTed files
818// - only used in FIT/RPA (which itself is almost NEVER used...)
819//
820Function GetLambdaFromReducedData(tempName)
821        String tempName
822       
823        String junkString
824        Variable lambdaFromFile, fileVar, junkVal
825        lambdaFromFile = 6.0
826
827        Open/R/P=catPathName fileVar as tempName
828        FReadLine fileVar, junkString
829        FReadLine fileVar, junkString
830        FReadLine fileVar, junkString
831        if(strsearch(LowerStr(junkString),"lambda",0) != -1)
832                FReadLine/N=11 fileVar, junkString
833                FReadLine/N=10 fileVar, junkString
834                sscanf  junkString, "%f",junkVal
835
836                lambdaFromFile = junkVal
837        endif
838        Close fileVar
839       
840        return(lambdaFromFile)
841End
842
843/////   TRANSMISSION RELATED FUNCTIONS    ////////
844//box coordinate are returned by reference
845//
846// box to sum over is bounded (x1,y1) to (x2,y2)
847//
848// this function returns the bounding coordinates as stored in
849// the header
850//
851// if not using the NCNR Transmission module, this function default to
852// returning 0000, and no changes needed
853Function getXYBoxFromFile(fname,x1,x2,y1,y2)
854        String fname
855        Variable &x1,&x2,&y1,&y2
856       
857        Variable refnum
858        String tmpFile = FindValidFilename(fname)
859        // tmpFile is only a parital path
860       
861        // return your bounding box coordinates or default values of 0
862        x1=getRealValueFromHeader(fname,"//XYBox_x1","")
863        x2=getRealValueFromHeader(fname,"//XYBox_x2","")
864        y1=getRealValueFromHeader(fname,"//XYBox_y1","")
865        y2=getRealValueFromHeader(fname,"//XYBox_y2","")
866       
867        if (x1 == -1 || x2 == -1 || y1 == -1 || y2 == -1)
868                x1 = 0
869                x2 = 0
870                y1 = 0
871                y2 = 0
872        endif
873       
874        return(0)
875End
876
877// Writes the coordinates of the box to the header after user input
878//
879// box to sum over bounded (x1,y1) to (x2,y2)
880//
881// if not using the NCNR Transmission module, this function is null
882Function WriteXYBoxToHeader(fname,x1,x2,y1,y2)
883        String fname
884        Variable x1,x2,y1,y2
885       
886        // your code to write bounding box to the header, or nothing
887        String x1str = "", x2str = "", y1str = "", y2str = ""
888        sprintf x1str, "%d", x1
889        sprintf x2str, "%d", x2
890        sprintf y1str, "%d", y1
891        sprintf y2str, "%d", y2
892
893        WriteHFIRHead(fname,x1str,"/SPICErack/XYBox_x1" ,"")   
894        WriteHFIRHead(fname,x2str,"/SPICErack/XYBox_x2" ,"")
895        WriteHFIRHead(fname,y1str,"/SPICErack/XYBox_y1" ,"")
896        WriteHFIRHead(fname,y2str,"/SPICErack/XYBox_y2" ,"")
897       
898        return(0)
899End
900
901// for transmission calculation, writes an NCNR-specific alphanumeric identifier
902// (suffix of the data file)
903//
904Function WriteAssocFileSuffixToHeader(fname,suffix)
905        String fname,suffix
906               
907       
908        WriteHFIRHead(fname,suffix,"/SPICErack/assoc_suffix" ,"text")
909        return(0)
910end
911
912
913//// ==================================================================
914//Keep these functions in case NIST changes: We need these...
915// TrimWhiteSpace (code from Jon Tischler)
916Function/T   HFIR_TrimWS(strg)
917   
918   String strg
919   return HFIR_TrimWSL(HFIR_TrimWSR(strg))
920End
921
922Function/T   HFIR_TrimWSL(strg)
923    String strg
924    Variable i, N=strlen(strg)
925    for (i=0;char2num(strg[i])<=32 && i<N;i+=1)    // find first non-white space
926    endfor
927    return strg[i,Inf]
928End
929
930Function/T   HFIR_TrimWSR(strg)
931    String strg
932    Variable i
933    for (i=strlen(strg)-1; char2num(strg[i])<=32 && i>=0; i-=1)    // find last non-white space
934   endfor
935    return strg[0,i]
936End
937//// ==================================================================
938
939Function ReadHFIRRaw(refNum,prtname,pname)   //NOT USED!!!!!!!!
940        Variable refNum
941        String pname, prtname
942       
943        //temp list of ns
944        MAKE/T/N=(1)/O nsList
945        nsList[0] = "1.1"
946       
947        // Check if  it is the SPICE version = 1.1
948        Variable  item,i
949        String thislocation, ns=""
950        Variable nns
951
952        for (item = 0; item < DimSize(nsList, 0); item += 1)            // loop over all possible namespaces
953                XMLlistAttr(refNum, prtname, nsList[item])
954                wave/T M_listAttr
955       
956                for (i = 0; i < DimSize(M_listAttr,0); i+=1)                    // loop over all available attributes
957                        // Expect the required hfir XML header (will fail if "schemalocation" is not found)
958                        if ( CmpStr(  LowerStr(M_listAttr[i][1]),  LowerStr(pname) ) == 0 )
959                                thisLocation = HFIR_TrimWS(M_listAttr[i][2])
960                                if ( StringMatch(thisLocation, nsList[item] + "*") )
961                                        ns = nsList[item]
962                                        Break
963                                endif
964                        endif
965                endfor
966                if (strlen(ns))
967                        Break           
968                endif
969        endfor
970        sscanf ns,"%f",nns
971return nns
972END
973
974
975////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
976//       Read ORNL HFIR SANS data ( xml format) file:general loading from display raw data
977////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
978Function ReadHFIRSansRaw(refNum,curFolder,tempheadhfir)
979    Variable refNum
980    String curFolder,tempheadhfir
981     
982        String curPath="root:Packages:NIST:"+curFolder
983        SetDataFolder curPath
984        Make/O/N=23 $(curPath+":IntegersRead")
985        Make/O/N=52 $(curPath+":RealsRead")
986        Make/O/T/N=11 $(curPath+":TextRead")
987       
988        Wave intw=$(curPath+":IntegersRead")
989        Wave realw=$(curPath+":RealsRead")
990        Wave/T textw=$(curPath+":TextRead")
991       
992        Variable ind,i,j,centerdata=1
993        Variable pixnumx=0,pixnumy=0
994        String val = "", pix_num = ""// numerical and text values
995        Variable value = 0.0,t1=ticks
996        String unitstr =""      //unit string
997
998        //Initialize wave values         
999         realw=0
1000         intw=0
1001         textw=""
1002         textw[2]=curFolder
1003         textw[3]=""
1004         textw[4]="C"                                ///???
1005         textw[7]="C"                        // temperature unit C
1006         textw[10]="xml"                        //HFIR SANS RAW data file extension
1007         realw[4]  = 1                          //Default for transmission for sample
1008         realw[12]=0.00                       //following 6 values are for non-linear spatial corrections to a detector (RC timing)
1009         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)
1010         realw[11]=10000.00                          //nonlinear spatial pix(x) //Do not change unless knowing what you are doing...
1011         realw[14]=10000.00                          //nonlinear spatial pix(y)
1012         // detector physical width (right now assumes square...) (in cm)
1013         // beam stop X-position (motor reading, approximate cm from zero position)
1014         // currently NCNR-specific use to identify transmission measurements
1015         // you return 0
1016         realw[37] = 0
1017         //textw[2]="RAW"      //????
1018 
1019//      Print "Time to list attributes (s) = ",(ticks-t1)/60.15
1020//      Print "Time to list elements (s) = ",(ticks-t1)/60.15
1021
1022        // Get and set the number of pixels from the line just above data.
1023        pix_num = XMLstrFmXpath(refNum,"//Data/Detector/@type","","")
1024        pixnumx=Str2num(StringFromList(0,StringFromList(1,pix_num ,","),"]"))   
1025        pixnumy=Str2num(StringFromList(1,StringFromList(0,pix_num ,","),"["))
1026        Variable/G root:myGlobals:gNPixelsX=pixnumx
1027        Variable/G root:myGlobals:gNPixelsY=pixnumy     
1028        SetDataFolder curPath
1029
1030                        //******Below deleted since HFIR prefers to use <Data type="INT32[xxx,xxx]" for pixnumbers
1031                        //********Leave the following lines in case they change the policy.
1032                        //if (stringmatch(tempheadhfir,"Number_of_X_Pixels")>0)                 
1033                        //      pixnumx=Str2num(val)     
1034                        //      Variable/G root:myGlobals:gNPixelsX=pixnumx     
1035                        //       SetDataFolder curPath
1036                        //elseif  (stringmatch(tempheadhfir,"Number_of_Y_Pixels")>0)
1037                        //      pixnumy=Str2num(val)
1038                        //      Variable/G root:myGlobals:gNPixelsY=pixnumy
1039                        //       SetDataFolder curPath
1040                        // Note for units: If in-unit is null, out will be unity.
1041                        textw[6] = XMLstrFmXpath(refNum,"//Header/Scan_Title","","")
1042               
1043                        textw[3] = XMLstrFmXpath(refNum,"//Header/Users","","")         //ToDo: Define   
1044                               
1045                        textw[9] = XMLstrFmXpath(refNum,"//Header/Instrument","","")                            //ToDo: Define
1046                       
1047                        value = ValfromUnit(refNum,"//Transmission_for_Sample","")
1048                        if (value <= 0)
1049                                value = 1               //HFIR default = -1 while NIST package not working if it is <=0: Set default =1. <=NOT good!!!
1050                        endif
1051                        realw[4] = value
1052                       
1053                        realw[3] = ValfromUnit(refNum,"//Motor_Positions/attenuation","percent")
1054                        realw[8] = ValfromUnit(refNum,"//Parameter_Positions/tsample","C")
1055                        realw[0] = ValfromUnit(refNum,"//Counters/monitor","")
1056                        realw[5] = ValfromUnit(refNum,"//Header/Sample_Thickness","cm")
1057                        realw[2] = ValfromUnit(refNum,"//Counters/psd","")       ////Need to check!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1058                        realw[10] = ValfromUnit(refNum,"//Header/x_mm_per_pixel","mm") 
1059                        realw[13] = ValfromUnit(refNum,"//Header/y_mm_per_pixel","mm") 
1060                        Variable/G root:myGlobals:PixelResDefault = unit_convert(realw[13],"mm","cm") //back to cm unit for this default value??!!
1061                        SetDataFolder curPath
1062                       
1063                        realw[16] = ValfromUnit(refNum,"//Header/beam_center_x_pixel","") 
1064                        realw[17] = ValfromUnit(refNum,"//Header/beam_center_y_pixel","") 
1065                        realw[21] = ValfromUnit(refNum,"//Motor_Positions/beam_trap_size","mm")    //what is different from the beam trap diameter in the file???
1066                        realw[18] = ValfromUnit(refNum,"//Motor_Positions/sample_det_dist","m")
1067                        intw[1]  = ValfromUnit(refNum,"//Counters/time","sec")     //Not supported. Assumed in "sec"
1068                        intw[2] = intw[1] //???
1069                        realw[23]  = ValfromUnit(refNum,"//Header/source_aperture_size","mm")      //diameter???
1070                        realw[24]  = ValfromUnit(refNum,"//Header/sample_aperture_size","mm")      //diameter???
1071                        realw[25]  = ValfromUnit(refNum,"//Header/source_distance","m")         
1072                        realw[26]  = ValfromUnit(refNum,"//Header/wavelength","a")     
1073                        realw[27]  = ValfromUnit(refNum,"//Header/wavelength_spread","")       
1074                       
1075                        //Set pixel numbers
1076                        //SetDataFolder curPath
1077                        NVAR pixnumx1= root:myGlobals:gNPixelsX                     
1078                        NVAR pixnumy1= root:myGlobals:gNPixelsY
1079                        Variable pixnx = pixnumx1, pixny = pixnumy1
1080                        realw[20] = realw[10]*pixnx/10.0                        // physical detector width  in cm  // ToDo: Need to check for ypix size???
1081                       
1082                        //prepare to get data
1083                        Make/O/N=(pixnumx1*pixnumy1) $(curPath+":data")
1084                        WAVE  data=$(curPath+":data")
1085                        //set the globals to the detector dimensions (pixels)
1086                        Redimension/N=(pixnx,pixny) data                        //ORNL pixnums are given from the data file
1087                        Variable intens = 0
1088       
1089                        // Read 2d data
1090                        XMLwaveFmXpath(refNum,"/SPICErack/Data/Detector",""," \t\n\r")
1091                        WAVE/T M_xmlContent
1092                        for (i=0;i<pixnx;i+=1)
1093                                for  (j=0;j<pixny;j+=1)
1094                                        sscanf M_xmlContent[j+i*pixny],"%i", intens
1095                                        data[i][j]=intens
1096                                endfor
1097                        endfor
1098                       
1099
1100                       
1101                        ///////unit test 1/2//////////////////////////////////////////////////////////////////////////////////////////////////////////////
1102                        //if  (stringmatch(tempheadhfir,"Detector")<1 ||stringmatch(tempheadhfir,"data"))
1103                        //      print tempheadhfir+"="+val+"["+unitstr+"]"
1104                        //endif
1105                        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1106               
1107
1108
1109          //If the data is a sensitivity data, need to be narmalize so that the average over the detector should be 1.
1110         If (stringmatch(curFolder, "DIV") >0)
1111                //Variable V_avg
1112                 WaveStats/Z/Q data
1113                data /= V_avg
1114          endif
1115                       
1116
1117        //keep a string of the filename in the RAW folder
1118       
1119        Variable strpos
1120               
1121        textw[0] = RemoveAllSpaces(XMLstrFmXpath(refNum,"//SPICErack/@filename","","") )    //////ShortFileName(RemoveAllSpaces(XMLstrFmXpath(refNum,"//SPICErack/@filename","","") )  )         // file name
1122        textw[1] =   XMLstrFmXpath(refNum,"//SPICErack/@start_time","","")              //Date and Time
1123        textw[5]=StringFromList(0,textw[1]," ")                                                                         //Date
1124       
1125        //String/G $(curPath+":FileList") = textw[0]
1126       
1127        ///////unit test 2/2//////////////////////////////////////////////////////////////////////////////////////////////////////////////
1128        //SetDataFolder curPath
1129        //print "****** ["+num2str(pixnx)+","+num2str(pixny)+"]*******"
1130        //for (i=0;i<Dimsize(textw,0);i+=1)
1131        //      print "textw["+num2str(i)+"] ="+textw[i]
1132        //endfor
1133        //for (i=0;i<Dimsize(realw,0);i+=1)
1134        //      print "realw["+num2str(i)+"] ="+num2str(realw[i])
1135        //endfor
1136        //for (i=0;i<Dimsize(intw,0);i+=1)
1137        //      print "intw["+num2str(i)+"] ="+num2str(intw[i])
1138        //endfor
1139        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1140        // We have everything from file: Need to close the file soon as possible
1141        XMLclosefile(refNum, 0)
1142        SetDataFolder curPath
1143        Killwaves/Z M_listXPath
1144End
1145
1146/// Get real value in NIST unit ///////////////////////////////////////////////////////////////////////////////////////////////////
1147Function ValfromUnit(refNum,wantedterm,NISTunit)
1148        Variable refNum    //FileID
1149        String wantedterm,NISTunit  //Xpath, value in string, unit from HFIR, unit from NIST
1150       
1151        String val="", unitstr=""
1152        Variable value = 0.0
1153        //SetDataFolder curPath ////????????/
1154       
1155        val =   XMLstrFmXpath(refNum,wantedterm,"","")
1156
1157        // Case of no value or zero value, check if written by HFIR Patch
1158        if (stringmatch(wantedterm,"//*")>0&& strlen(val) ==0)
1159                 wantedterm = "//" +  StringFromList(3, wantedterm,"//")
1160                 // if valid wnatedterm
1161                 if (strlen(wantedterm) >1)
1162                        val =   XMLstrFmXpath(refNum,wantedterm,"","")
1163                 endif
1164        endif   
1165        unitstr =  RemoveAllSpaces(XMLstrFmXpath(refNum,wantedterm+"/@units","",""))
1166       
1167        //The units of the source_distance is treated special...
1168        if (stringmatch(wantedterm,"*source_distance")>0 )
1169                if  (strlen(unitstr)==0)
1170                        unitstr = "mm"          //Give mm unit since no unit is provided from the file. ///This needs to be corrected soon!!!!
1171                 endif
1172        endif
1173        //String to double
1174        sscanf val, "%f", value
1175        Variable data
1176        data = unit_convert(value,unitstr,NISTunit)
1177
1178        return data
1179End
1180
1181
1182//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1183//Read Real Values from HFIR data 
1184//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1185Function ReadVFromHHead(refNum,wantedterm,NCunit)
1186      Variable refNum
1187      String wantedterm, NCunit
1188     
1189      Variable vresult=-1  // (wantedterm=="", return -1)
1190        Variable ind=0,i=0, value = 0
1191        String  ntype = ""
1192        String savedDataFolder = GetDataFolder(1)
1193        //Default for transmission rate (between 0 to 1): HFIR not provide this as a Float number???? ==>make one: if exist, read it below.
1194        if (stringmatch(wantedterm,"//Transmission_for_Sample")>0)
1195                vresult=1               
1196        endif
1197       
1198        String unitstr = "", typestr="",tempheadhfir="", val=""
1199
1200        if (stringmatch(wantedterm,"") >0 ) // set zero if wnatedterm is "" ,not defined(eg., rotation angle).
1201                vresult =0
1202                //close here
1203                XMLclosefile(refNum, 0)
1204                return vresult
1205        else
1206                //Find the value,unit, and type of the value: a little ugly but faster...
1207                val =   XMLstrFmXpath(refNum,wantedterm,"","")
1208                // Case of no value or zero value, check if it written by HFIR Patch
1209                if (stringmatch(wantedterm,"//*")>0&& strlen(val) ==0)
1210                        wantedterm = "//" +  StringFromList(3, wantedterm,"//")
1211                        // if valid wnatedterm
1212                        if (strlen(wantedterm) >1)
1213                                val =   XMLstrFmXpath(refNum,wantedterm,"","")
1214                        endif
1215                endif
1216                unitstr =  RemoveAllSpaces(XMLstrFmXpath(refNum,wantedterm+"/@units","",""))
1217                typestr =  RemoveAllSpaces(XMLstrFmXpath(refNum,wantedterm+"/@type","",""))
1218                //close here
1219                XMLclosefile(refNum, 0)
1220        endif
1221       
1222        if   (stringmatch(typestr , "INT*")>0)
1223                ntype = "i"             //INT32
1224        elseif (stringmatch(typestr , "FLOAT*")>0)
1225                ntype ="f"              //FLOAT32
1226        else
1227                ntype ="s"              //TEXT
1228        endif   
1229       
1230        String ustr ="%f"                               //default: float
1231        if (stringmatch(ntype,"i") > 0) //for integer   
1232                ustr = "%d"
1233        endif   
1234                                       
1235        //Special case starts!!!
1236        //No unit found in hfir ("mm") but needs to convert to meters.
1237        //The following 3 lines should be removed once HFIR puts th units on the raw data files.
1238        if (stringmatch(wantedterm,"*source_distance")>0&& strlen(unitstr) ==0)
1239                unitstr = "mm"         
1240        endif
1241        //Special case ends!!!
1242       
1243        //Do NOT use str2num(): will loose many decimal digits.
1244        sscanf val, ustr, value
1245        vresult = unit_convert(value,unitstr,NCunit)
1246        if (stringmatch(wantedterm,"*Transmission_for_Sample")>0 && vresult == 0)
1247                 //Transmission default value if it was set to 0.
1248                 vresult = 1
1249        endif
1250                       
1251        //Set PixResDefault from y_mm_per_pixel (not x_mm_per_pixel!!!!!!!!)
1252        if (stringmatch(wantedterm,"*y_mm_per_pixel")>0)
1253                 Variable/G root:myGlobals:PixelResDefault = unit_convert(vresult,"mm","cm") //back to cm unit for this default value??!!
1254                 SetDataFolder savedDataFolder          //In case...
1255        endif
1256
1257               
1258        return (vresult)
1259
1260End
1261
1262/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1263//Read Strings from HFIR data 
1264/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1265Function/S ReadSFromHHead(refNum,wantedterm)
1266      Variable refNum
1267      String wantedterm
1268     
1269      String tempheadhfir = ""
1270      String result = "",gotterm ="n" ,name
1271        Variable ind,i
1272
1273      if   (stringmatch(wantedterm,"")>0)
1274                result = ""
1275                XMLclosefile(refNum, 0)
1276                return (result)
1277        endif
1278       
1279        result =  XMLstrFmXpath(refNum,wantedterm,"","")
1280        if (stringmatch(result, "") != -1 )     
1281                gotterm ="y"   
1282        endif
1283
1284        //HFIR header does not have "suffix" tag but one can get the info from file name before user writes the tag into the header.
1285        if (stringmatch("",result)>0     && stringmatch("//suffix",wantedterm)>0 )
1286                name = RemoveAllSpaces(XMLstrFmXpath(refNum,"//SPICErack/@filename","",""))
1287                result=StringFromList(2,StringFromList(0, name,"."), "_")+"_"+StringFromList(3,StringFromList(0,name,"."), "_")
1288        endif
1289
1290        //Close file here.
1291        XMLclosefile(refNum, 0)
1292       
1293        if (stringmatch(gotterm,"n")>0 )
1294                result = ""
1295        endif   
1296
1297      return (result)
1298End
1299
1300
1301//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1302//WRITE Real Values to HFIR data file 
1303//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1304
1305Function WriteHFIRHead(filename,value,wantedterm,NCunit)
1306     
1307      String filename, value,wantedterm, NCunit //where value is a string...
1308     
1309        String valstr
1310      Variable/D vresult = 0
1311      Variable refNum
1312        Variable ind=0,i=0, vals
1313       
1314        Variable typenum = 0
1315        String ntype = ""       //Do not change this initial, "".
1316        String nstr = "/SPICErack"              //to add new nodes and content: NEVER CAHNGE this string
1317        String errorMsg =""
1318       
1319        //print "Loading", filename, "..."
1320        if (stringmatch(filename,"*.xml") <1)
1321                //print "\r  ==>  Failed: Not a *.xml file."
1322                return 0                                //Not *.xml. Do nothing...
1323        endif
1324        //actually open the file
1325        refNum = XmlOpenFile(filename) 
1326
1327        if (refNum < 0)
1328                switch(refNum)                                 
1329                        case -1:
1330                                errorMsg = errorMsg+filename+ "  ==>  Not a standard xml file format; Please check if the file is not broken..."
1331                        break
1332                        case -2:
1333                                errorMsg = errorMsg+filename+"  ==>  Please check if the file name is same as that written in the header..."
1334                        break
1335                endswitch
1336                print errorMsg
1337                XMLclosefile(refNum, 0)
1338                return -1                               //Not a xml file. Do nothing...
1339        endif
1340
1341                String unitstr = "",typestr="", val=""
1342
1343                if  (strlen(wantedterm)==0)     
1344                        vresult =0                              //If input is NULL, do nothing...
1345                        nstr = ""                                       //reset as No new node
1346
1347                else   //(stringmatch(tempheadhfir,wantedterm)>0)       
1348                        val =   XMLstrFmXpath(refNum,wantedterm,"","")
1349                        // if no regular entry is found, check patch entry.
1350                        if (stringmatch(wantedterm,"//*")>0&& strlen(val) ==0)
1351                                wantedterm = "//" +  StringFromList(3, wantedterm,"//")
1352                                // if valid wnatedterm
1353                                if (strlen(wantedterm) >1)
1354                                        val =   XMLstrFmXpath(refNum,wantedterm,"","")
1355                                endif
1356                        endif
1357                        //Special case starts!!!
1358                        //No unit founds in hfir ("mm") file but needs to convert to meters. Let's give it one.
1359                        if (stringmatch(wantedterm,"*source_distance")>0&& strlen(unitstr) ==0)
1360                                unitstr = "mm" 
1361                                ntype ="f"     
1362                        //Special case ends!!!
1363                        else
1364                                unitstr =  XMLstrFmXpath(refNum,wantedterm+"/@units","","")
1365                                typestr =  RemoveAllSpaces(XMLstrFmXpath(refNum,wantedterm+"/@type","",""))
1366       
1367                                ntype ="s"              //TEXT 
1368                               
1369                                        if  (strlen(typestr)==0)
1370                                                ntype = "s"
1371                                        elseif   (stringmatch(typestr, "INT*")>0)
1372                                                ntype = "i"             //INT32
1373                                        elseif (stringmatch(typestr, "FLOAT*")>0)
1374                                                ntype ="f"              //FLOAT32
1375                                        endif   
1376                        endif
1377                       
1378                        if (stringmatch(ntype,"s") > 0) //for strings           
1379                                vresult = 1                     
1380                                valstr =value
1381                        else
1382                                String ustr ="%f"                               //default: float
1383                                if (stringmatch(ntype,"i") > 0) //for integer   
1384                                        ustr = "%d"
1385                                endif                   
1386                                sscanf  value,ustr, vals
1387                                vresult = unit_convert(vals,NCunit,unitstr)     //Unit correction...(back to the HFIR unit)
1388                               
1389                                sprintf valstr,ustr, vresult
1390                        endif
1391                       
1392                        if (stringmatch(wantedterm,"/SPICErack/*")>0&& strlen(val) ==0)
1393                                nstr = "/SPICErack"
1394                                // remove "/SPICErack/" from wantedterm
1395                                wantedterm = StringFromList(2, wantedterm,"/SPICErack/")
1396                        elseif (stringmatch(wantedterm,"//*")>0&& strlen(val) ==0)
1397                                nstr = "/SPICErack"
1398                                //remove'//' to wantedterm
1399                                wantedterm = StringFromList(2, wantedterm,"//")
1400                        else
1401                                XMLsetNodeStr(refNum,wantedterm,"",valstr)      //to set
1402                                nstr = ""                               //reset as No new node
1403                        endif
1404                        //break
1405                 endif         
1406        //to write new  attr name and value which are not found in the raw file.
1407        if (strlen(nstr)>2)                             
1408                 XMLaddNode(refNum,nstr,"",wantedterm,value,1)
1409                 // nstr to add new node
1410                 nstr = "//"+wantedterm
1411                 // get unit
1412                 if (stringmatch(NCunit,"text")>0)     
1413                        ntype = "text"
1414                        vresult = 1
1415                 else
1416                        XMLsetAttr(refNum,nstr,"","units",NCunit)       //use NIST units.
1417                        ntype = "FLOAT32"                                               //Let's set the any number as float for now... 
1418                        sscanf  value, "%f", vals
1419                        vresult = vals         
1420                 endif
1421                 //print "*** Note:*** \r     *** No parameter named",wantedterm, "was found, so it was added to the end of your data file."
1422                 XMLsetAttr(refNum,nstr,"","type",ntype)       
1423        endif
1424
1425        //KillWaves/Z W_ElementList,M_xmlContent,M_listXPath,M_listAttr                 //clean up
1426        if      (strlen(wantedterm)==0 && vresult == -1)
1427                XMLclosefile(refNum, 0)
1428                //print "Failed writing",wantedterm, "on", filename, "..."
1429        else
1430                XMLclosefile(refNum, 1)                                         //save and close the file.
1431                //print "Finished writing",wantedterm,"=",value,"[",NCunit,"]  on", filename, "..."
1432        endif
1433        return (vresult)
1434
1435End
1436
1437
1438Function UserGetWLPanel_ContButton(cntrlName)
1439      String cntrlName
1440      DoWindow /K WaveLengthInput
1441End
1442
1443Function Daskcheckbox(cntrlName,checked)
1444String cntrlName
1445Variable checked
1446
1447Wave realw=$"root:RAW:RealsRead"
1448Variable/G root:myGlobals:globDask=checked
1449      if (checked==1)
1450           Variable /G root:myGlobals:globwlfix=realw[26]
1451           Variable /G root:myGlobals:globdwlfix=realw[27]
1452      endif
1453
1454 End
1455 
1456 
1457Function Daskcheckbox1(cntrlName,checked)
1458String cntrlName
1459Variable checked
1460
1461Wave templw=$"root:RAW:tempwave1"
1462Variable/G root:myGlobals:globDask1=checked
1463      if (checked==1)
1464           Variable /G root:myGlobals:globwlfix=templw[0]
1465           Variable /G root:myGlobals:globdwlfix=templw[1]
1466      endif
1467
1468 End
1469 
1470//Write whether Transmission is True or False.
1471Function Write_isTransmissionToHeader(fname,str)
1472        String fname,str
1473
1474        WriteHFIRHead(fname,str, "//Header/Transmission","text")       
1475        return(0)
1476End
1477
1478//sample transmission is a real value at byte 158
1479Function WriteTransmissionToHeader(fname,trans)
1480        String fname
1481        Variable trans
1482
1483        String transstr = ""
1484        sprintf transstr, "%f", trans
1485
1486         WriteHFIRHead(fname,transstr,"/SPICErack/Transmission_for_Sample" ,"")                 
1487        return(0)
1488End
1489
1490//whole transmission is a real value at byte 392
1491Function WriteWholeTransToHeader(fname,trans)
1492        String fname
1493        Variable trans
1494
1495        String transstr = ""
1496        sprintf transstr, "%f", trans
1497
1498        WriteHFIRHead(fname,transstr,"//Counters/detector" ,"")         //????????????????????????????????????????????????????????
1499        return(0)
1500End
1501
1502//box sum counts is a real value
1503// used for transmission calculation module
1504//box sum counts is a real value at byte 494
1505Function WriteBoxCountsToHeader(fname,counts)
1506        String fname
1507        Variable counts
1508
1509        String countsstr = ""
1510        sprintf countsstr, "%f", counts
1511
1512        WriteHFIRHead(fname,countsstr,"/SPICErack/Box_Counts" ,"")     
1513        return(0)
1514End
1515
1516//Below units refer to NIST units..
1517//beam stop X-pos is at byte 368
1518Function WriteBSXPosToHeader(fname,xpos)
1519        String fname
1520        Variable xpos
1521
1522        String xposstr = ""
1523        sprintf xposstr, "%f", xpos
1524
1525        WriteHFIRHead(fname,xposstr,"//Motor_Positions/beam_trap_x","mm")       ///Is this diameter?
1526        return(0)
1527End
1528
1529//sample thickness is at byte 162
1530Function WriteThicknessToHeader(fname,num)
1531        String fname
1532        Variable num
1533
1534        String numstr = ""
1535        sprintf numstr, "%f", num
1536
1537        WriteHFIRHead(fname,numstr,"//Header/Sample_Thickness","cm")
1538        return(0)
1539End
1540
1541//beam center X pixel location is at byte 252
1542Function WriteBeamCenterXToHeader(fname,num)
1543        String fname
1544        Variable num
1545
1546        String numstr = ""
1547        sprintf numstr, "%f", num
1548
1549        WriteHFIRHead(fname,numstr,"//Header/beam_center_x_pixel" ,"")
1550        return(0)
1551End
1552
1553//beam center Y pixel location is at byte 256
1554Function WriteBeamCenterYToHeader(fname,num)
1555        String fname
1556        Variable num
1557
1558        String numstr = ""
1559        sprintf numstr, "%f", num
1560
1561        WriteHFIRHead(fname,numstr,"//Header/beam_center_y_pixel","")
1562        return(0)
1563End
1564
1565//Attenuation (percent) 0 for no attanuation (not its transmission)
1566Function WriteAttenNumberToHeader(fname,num)
1567        String fname
1568        Variable num
1569
1570        String numstr = ""
1571        sprintf numstr, "%f", num
1572
1573        WriteHFIRHead(fname,numstr,"//Motor_Positions/attenuation","percent")   // HFIR has attenuation % instead of this. thus user has to use patch unless somebody change the format!!!!
1574        return(0)
1575End
1576
1577//monitor count is at byte 39
1578Function WriteMonitorCountToHeader(fname,num)
1579        String fname
1580        Variable num
1581
1582        String numstr = ""
1583        sprintf numstr, "%f", num
1584
1585        WriteHFIRHead(fname,numstr,"//Counters/monitor","")
1586        return(0)
1587End
1588
1589//total detector count is at byte 47
1590Function WriteDetectorCountToHeader(fname,num)
1591        String fname
1592        Variable num
1593
1594        String numstr = ""
1595        sprintf numstr, "%f", num
1596
1597        WriteHFIRHead(fname,numstr,"//Counters/psd","")
1598        return(0)
1599End
1600
1601//transmission detector count is at byte 388
1602Function WriteTransDetCountToHeader(fname,num)
1603        String fname
1604        Variable num
1605
1606        String numstr = ""
1607        sprintf numstr, "%f", num
1608
1609        WriteHFIRHead(fname,numstr,"//Counters/detector","")   ///Check with Steve & Ken!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1610        return(0)
1611End
1612
1613//wavelength is at byte 292
1614Function WriteWavelengthToHeader(fname,num)
1615        String fname
1616        Variable num
1617
1618        String numstr = ""
1619        sprintf numstr, "%f", num
1620
1621        WriteHFIRHead(fname,numstr,"//Header/wavelength" ,"angstroms")
1622        return(0)
1623End
1624
1625//wavelength spread is at byte 296
1626Function WriteWavelengthDistrToHeader(fname,num)
1627        String fname
1628        Variable num
1629
1630        String numstr = ""
1631        sprintf numstr, "%f", num
1632
1633        WriteHFIRHead(fname,numstr,"//Header/wavelength_spread","")
1634        return(0)
1635End
1636
1637//temperature is at byte 186
1638Function WriteTemperatureToHeader(fname,num)
1639        String fname
1640        Variable num
1641
1642        String numstr = ""
1643        sprintf numstr, "%f", num
1644
1645        WriteHFIRHead(fname,numstr,"//Parameter_Positions/tsample" ,"C")
1646        return(0)
1647End
1648
1649//magnetic field is at byte 190
1650Function WriteMagnFieldToHeader(fname,num)
1651        String fname
1652        Variable num
1653
1654        String numstr = ""
1655        sprintf numstr, "%f", num
1656
1657        WriteHFIRHead(fname,numstr,"/SPICErack/magnetic_field","G")  //Not defined on HFIR file...  Should be changed the name when decided...
1658        return(0)
1659End
1660
1661//Source Aperture diameter is at byte 280
1662Function WriteSourceApDiamToHeader(fname,num)
1663        String fname
1664        Variable num
1665
1666        String numstr = ""
1667        sprintf numstr, "%f", num
1668
1669        WriteHFIRHead(fname,numstr,"//Header/source_aperture_size","mm")
1670        return(0)
1671End
1672
1673//Sample Aperture diameter is at byte 284
1674Function WriteSampleApDiamToHeader(fname,num)
1675        String fname
1676        Variable num
1677
1678        String numstr = ""
1679        sprintf numstr, "%f", num
1680
1681        WriteHFIRHead(fname,numstr,"//Header/sample_aperture_size","mm")
1682        return(0)
1683End
1684
1685//Source to sample distance is at byte 288
1686Function WriteSrcToSamDistToHeader(fname,num)
1687        String fname
1688        Variable num
1689
1690        String numstr = ""
1691        sprintf numstr, "%f", num
1692
1693        WriteHFIRHead(fname,numstr,"//Header/source_distance","m")     //unit=m   :hfir = mm ???????????????
1694        return(0)
1695End
1696
1697//detector offset is at byte 264
1698Function WriteDetectorOffsetToHeader(fname,num)
1699        String fname
1700        Variable num
1701
1702        String numstr = ""
1703        sprintf numstr, "%f", num
1704
1705        WriteHFIRHead(fname,numstr,"//Header/detector_trans","cm")  //cm:  HFIR = mm !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1706        return(0)
1707End
1708
1709//beam stop diameter is at byte 272
1710Function WriteBeamStopDiamToHeader(fname,num)
1711        String fname
1712        Variable num
1713       
1714        String numstr = ""
1715        sprintf numstr, "%f", num
1716       
1717        WriteHFIRHead(fname,numstr,"//Motor_Positions/beam_trap_size","mm")  //check !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1718        return(0)
1719End
1720
1721//sample to detector distance is at byte 260
1722Function WriteSDDToHeader(fname,num)
1723        String fname
1724        Variable num
1725
1726        String numstr = ""
1727        sprintf numstr, "%f", num
1728       
1729        WriteHFIRHead(fname,numstr,"//Motor_Positions/sample_det_dist","m")
1730        return(0)
1731End
1732
1733//detector pixel X size (mm) is at byte 220
1734Function WriteDetPixelXToHeader(fname,num)
1735        String fname
1736        Variable num
1737
1738        String numstr = ""
1739        sprintf numstr, "%f", num
1740       
1741        WriteHFIRHead(fname,numstr, "//Header/x_mm_per_pixel","mm")
1742        return(0)
1743End
1744
1745//detector pixel Y size (mm) is at byte 232
1746Function WriteDetPixelYToHeader(fname,num)
1747        String fname
1748        Variable num
1749       
1750        String numstr = ""
1751        sprintf numstr, "%f", num
1752       
1753        WriteHFIRHead(fname,numstr, "//Header/y_mm_per_pixel","mm")
1754        return(0)
1755End
1756
1757// sample label
1758// limit to 60 characters
1759Function WriteSamLabelToHeader(fname,str)
1760        String fname,str
1761       
1762        if(strlen(str) > 60)
1763                str = str[0,59]
1764        endif
1765        WriteHFIRHead(fname,str, "//Header/Scan_Title","text") //Users tend to put the sample descrpt here instead of "Sample_Name"...
1766        return(0)
1767End
1768
1769
1770Function WriteCountTimeToHeader(fname,num)
1771        String fname
1772        Variable num
1773       
1774        String numstr = ""
1775        sprintf numstr, "%f", num
1776       
1777        WriteHFIRHead(fname,numstr,"//Counters/time","sec")
1778        return(0)
1779End
1780
1781
1782/////Handy Unit converter for length & time units"
1783Function length_unit_convert(from,to)  // input: ("m", cm")==> output=10,....;   input: ("", "") ==> out = 1
1784        String from, to
1785       
1786        Variable i, out
1787       
1788        Make/O/T/N=(18,2) munit
1789       
1790        //ToDo: to combine the same units       
1791        //length units
1792        munit[0][0]="m"   //popular units first...
1793        munit[0][1]= "1"
1794        munit[1][0]="cm"
1795        munit[1][1]= "0.01"
1796        munit[2][0]="mm"
1797        munit[2][1]= "0.001"
1798        munit[3][0]="angstroms"  //HFIR used this rather than A
1799        munit[3][1]= "1e-10"
1800        munit[4][0]="meters"
1801        munit[4][1]= "1"
1802        munit[5][0]="um"
1803        munit[5][1]= "1e-06"
1804        munit[6][0]="nm"
1805        munit[6][1]= "1e-09"
1806        munit[7][0]="km"
1807        munit[7][1]= "1000"
1808        munit[8][0]="a"
1809        munit[8][1]= "1e-10"
1810        munit[9][0]="angstrom"
1811        munit[9][1]= "1e-10"
1812        munit[10][0]="microns"
1813        munit[10][1]= "1e-6"
1814        munit[11][0]="meter"
1815        munit[11][1]= "1"
1816       
1817        //time units
1818        munit[12][0]="sec"
1819        munit[12][1]= "1"
1820        munit[13][0]="seconds"
1821        munit[13][1]= "1"
1822        munit[14][0]="min"
1823        munit[14][1]= "60"
1824        munit[15][0]="minutes"
1825        munit[15][1]= "60"
1826        munit[16][0]="hrs"
1827        munit[16][1]= "3600"
1828        munit[17][0]="hours"
1829        munit[17][1]= "3600"
1830        //Add more units here...
1831         
1832        String  v_from="", v_to=""
1833        for (i = 0; i<DimSize(munit,0); i+=1)
1834                if (stringmatch(munit[i][0],from)>0)  // IgorPro "stringmatch()" function handles both lower & upper cases.
1835                        v_from = munit[i][1]
1836                        break
1837                endif
1838        endfor
1839       
1840        for (i = 0; i<DimSize(munit,0); i+=1)
1841                if (stringmatch(munit[i][0],to)>0)
1842                        v_to = munit[i][1]
1843                        break
1844                endif
1845        endfor
1846       
1847        KillWaves/Z munit
1848       
1849       
1850        if (strlen(v_from)==0 || strlen(v_to) ==0)
1851                out = 1                 //Do nothing...
1852        else
1853                Variable vf, vt
1854                sscanf  v_to, "%f", vt
1855                sscanf  v_from, "%f", vf
1856                out = vf / vt
1857        endif
1858        return out
1859End
1860
1861
1862///For length and temperature units
1863Function unit_convert(val, from,to)  // input: ("m", cm")==> output=10,....;   input: ("", "") ==> out = 1
1864        Variable val
1865        String from, to
1866
1867        from = RemoveAllSpaces(from)
1868        to = RemoveAllSpaces(to)
1869                       
1870        Variable i, out = val
1871
1872        //Search for two same strings, or one with none.
1873        if (stringmatch(from,to)>0 ||strlen(from) == 0||strlen(to)==0)
1874                out = val
1875               
1876        //Temperature unit: support only C and K
1877        elseif (stringmatch(from,"C")>0 || stringmatch(to,"K")>0||stringmatch(to,"C")>0 || stringmatch(from,"K")>0)
1878                out =temp_unit_convert(val, from,to)
1879               
1880        //Length unit                   
1881        else
1882                out = val*length_unit_convert(from,to)                                                 
1883        endif
1884
1885        return out
1886End
1887
1888//temperature unit converter: Only support K and C.
1889Function temp_unit_convert(val, from,to) 
1890        Variable val
1891        String from, to
1892       
1893        Variable i, j, out = val
1894
1895        Make/O/T/N=(2,2) tunit
1896       
1897        tunit[0][0]="C"   //popular units first...
1898        tunit[0][1]= "-273.15"
1899        tunit[1][0]="K"
1900        tunit[1][1]= "0"       
1901
1902        String  v_from="", v_to=""
1903
1904        for (i = 0; i<DimSize(tunit,0); i+=1)
1905                if (stringmatch(tunit[i][0],from)==1)  // IgorPro "stringmatch()" function handles both lower & upper cases.
1906                        v_from = tunit[i][1]
1907                        break
1908                endif
1909        endfor
1910
1911        for (j = 0; j<DimSize(tunit,0); j+=1)
1912                if (stringmatch(tunit[j][0],to)==1)
1913                        v_to = tunit[j][1]
1914                        break
1915                endif   
1916        endfor 
1917        KillWaves/Z tunit
1918        if (strlen(v_from)==0 || strlen(v_to) ==0)
1919                out = 1                 //Do nothing...
1920        else
1921                Variable vt, vf
1922                sscanf  v_to, "%f", vt
1923                sscanf  v_from, "%f", vf
1924                out = val + (vt - vf)
1925        endif
1926        return out
1927End
1928
1929
1930///This function make HFIR SANS data file shorter which is more than 30 characters causing problem taking other names after the file name.
1931//Will remove instrumental name.
1932Function/S ShortFileName(fileName)
1933        String fileName
1934        //Default: just passing
1935        String fname = fileName
1936
1937        //Check whether it is from HiResSANS or BioSANS and remove the head
1938        if (stringmatch(fileName,"HiResSANS_*.*")>0 )
1939                fname = ReplaceString("HiResSANS_",fname,"HS_",0,1)   
1940        elseif (stringmatch(filename,"BioSANS_*.*")>0)
1941                fname = ReplaceString("BioSANS_",fname,"BS_",0,1)     
1942        endif
1943        return fname
1944END
1945
1946//Not used
1947///This function return the original HFIR SANS data file name that was shorten before.
1948//Put them back to HiResSANS*** or BioSANS***.
1949Function/S FullFileName(fname)
1950        String fname
1951        //Default: just passing
1952        String fileName = fname
1953       
1954        //Check whether it is from HiResSANS or BioSANS
1955        if (stringmatch(fname,"*HS_*.*")>0 )
1956                fileName = ReplaceString("HS_",fname,"HiResSANS_",0,1) 
1957        elseif (stringmatch(fname,"*BS_*.*")>0)
1958                fileName = ReplaceString("BS_",fname,"BioSANS_",0,1)   
1959        endif
1960
1961        return fileName
1962END
1963
1964
1965///Find file name from full Path+file
1966Function/S GetFName(path,  length)
1967        String path
1968        Variable length // 1 for full name, 0 for shorten name, others pass the name
1969       
1970        Variable index
1971        String ofname, mfname
1972       
1973        // get index of the file name
1974        index = ItemsInList(path,":") - 1
1975        // get file name
1976        ofname = StringFromList(index,path,":")
1977        //modify the name if need otherwise return w/o change
1978        if (length == 0)
1979                mfname = ShortFileName(ofname)
1980        elseif (length == 1)
1981                mfname = FullFileName(ofname)
1982        else
1983                mfname = ofname
1984        endif
1985        // return the path+modified file name
1986        return mfname
1987End
1988
1989
1990///Find file name from full Path+file and replace file name to a shorter or full name in path+file.
1991Function/S ReplaceFName(path,  length)
1992        String path
1993        Variable length // 1 for full name, 0 for shorten name
1994       
1995        Variable index
1996        String ofname,mfname
1997       
1998        // get index of the file name
1999        index = ItemsInList(path,":") - 1
2000        // get file name
2001        ofname = StringFromList(index,path,":")
2002        //modify the name if need otherwise return w/o change
2003        if (length == 0)
2004                mfname = ShortFileName(ofname)
2005        else
2006                mfname = FullFileName(ofname)
2007        endif
2008        // return the path+modified file name
2009        return ReplaceString(ofname,path,mfname,0,1)
2010End
2011
2012////Unused ///Not working well
2013// Change file name before and after Xml open
2014Function/S XmlFileOpen(fname)
2015        String fname
2016       
2017        // fname = path + full file name
2018        fname = ReplaceFName(fname,  1)
2019        XmlOpenFile(fname)
2020        // path + short file name
2021        return ReplaceFName(fname,  0)
2022End
2023
2024
2025////// OCT 2009, facility specific bits from ProDiv()
2026//"type" is the data folder that has the corrected, patched, and normalized DIV data array
2027//
2028// the header of this file is rather unimportant. Filling in a title at least would be helpful/
2029//
2030Function Write_DIV_File(type)
2031        String type
2032       
2033        // Your file writing function here. Don't try to duplicate the VAX binary format...
2034       
2035        return(0)
2036End
2037
2038////// OCT 2009, facility specific bits from MonteCarlo functions()
2039//"type" is the data folder that has the data array that is to be (re)written as a full
2040// data file, as if it was a raw data file
2041//
2042// not really necessary
2043//
2044Function Write_RawData_File(type,fullpath,dialog)
2045        String type,fullpath
2046        Variable dialog         //=1 will present dialog for name
2047       
2048        // Your file writing function here. Don't try to duplicate the VAX binary format...
2049        Print "Write_RawData_File stub"
2050       
2051        return(0)
2052End
Note: See TracBrowser for help on using the repository browser.