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

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

fixed some sloppy logic in converting log/lin data. Now the raw data readers create data (for display) and linear_data (to keep) upon loading.

Updated the Histogram Pair with Cedric's suggestions. width is adjustable, and the cursor is more visible.

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