#pragma rtGlobals=1 // Use modern global access method. #pragma version=5.0 #pragma IgorVersion=6.1 //************************** // // Vers. 1.2 092101 // Vers. 5.0 29MAR07 - branched from main reduction to split out facility // specific calls // // functions for reading raw data files from the VAX // - RAW data files are read into the RAW folder - integer data from the detector // is decompressed and given the proper orientation // - header information is placed into real,integer, or text waves in the order they appear // in the file header // // Work data (DIV File) is read into the DIV folder // //***************************** //simple, main entry procedure that will load a RAW sans data file (not a work file) //into the RAW dataFolder. It is up to the calling procedure to display the file // // called by MainPanel.ipf and ProtocolAsPanel.ipf // Function LoadRawSANSData(msgStr) String msgStr String filename="" //each routine is responsible for checking the current (displayed) data folder //selecting it, and returning to root when done PathInfo/S catPathName //should set the next dialog to the proper path... //get the filename, then read it in filename = PromptForPath(msgStr) //in SANS_Utils.ipf //check for cancel from dialog if(strlen(filename)==0) //user cancelled, abort SetDataFolder root: DoAlert 0, "No file selected, action aborted" return(1) Endif ReadHeaderAndData(filename) //this is the full Path+file Return(0) End //function that does the guts of reading the binary data file //fname is the full path:name;vers required to open the file // // The final root:RAW:data wave is the real //neutron counts and can be directly operated on // // header information is put into three waves: integersRead, realsRead, and textRead // logicals in the header are currently skipped, since they are no use in the // data reduction process. // // The output is the three R/T/I waves that are filled at least with minimal values // and the detector data loaded into an array named "data" // // see documentation for the expected information in each element of the R/T/I waves // and the minimum set of information. These waves can be increased in length so that // more information can be accessed as needed (propagating changes...) // // called by multiple .ipfs (when the file name is known) // // // THIS FUNCTION DOES NOT NEED TO BE MODIFIED. ONLY THE DATA ACCESSORS NEED TO BE CONSTRUCTED // Function ReadHeaderAndData(fname) String fname //this function is for reading in RAW data only, so it will always put data in RAW folder String curPath = "root:Packages:NIST:RAW:" SetDataFolder curPath //use the full path, so it will always work Variable/G root:Packages:NIST:RAW:gIsLogScale = 0 //initial state is linear, keep this in RAW folder Variable refNum,integer,realval String sansfname,textstr Make/O/D/N=23 $"root:Packages:NIST:RAW:IntegersRead" Make/O/D/N=52 $"root:Packages:NIST:RAW:RealsRead" Make/O/T/N=11 $"root:Packages:NIST:RAW:TextRead" Make/O/N=7 $"root:Packages:NIST:RAW:LogicalsRead" Wave intw=$"root:Packages:NIST:RAW:IntegersRead" Wave realw=$"root:Packages:NIST:RAW:RealsRead" Wave/T textw=$"root:Packages:NIST:RAW:TextRead" Wave logw=$"root:Packages:NIST:RAW:LogicalsRead" // FILL IN 3 ARRAYS WITH HEADER INFORMATION FOR LATER USE // THESE ARE JUST THE MINIMALLY NECESSARY VALUES // filename as stored in the file header textw[0]= fname // date and time of collection textw[1]= getFileCreationDate(fname) // run type identifier (this is a reader for RAW data) textw[2]= "RAW" // user account identifier (currently used only for NCNR-specific operations) textw[3]= "" // sample label textw[6]= getSampleLabel(fname) // identifier of detector type, useful for setting detector constants //(currently used only for NCNR-specific operations) textw[9]= "" //total counting time in seconds intw[2] = getCountTime(fname) // total monitor count realw[0] = getMonitorCount(fname) // total detector count realw[2] = getDetCount(fname) // attenuator number (NCNR-specific, your stub returns 0) // may also be used to hold attenuator transmission (< 1) realw[3] = getAttenNumber(fname) // sample transmission realw[4] = getSampleTrans(fname) //sample thickness (cm) realw[5] = getSampleThickness(fname) // following 6 values are for non-linear spatial corrections to a detector (RC timing) // these values are set for a detctor that has a linear correspondence between // pixel number and real-space distance // 10 and 13 are the X and Y pixel dimensions, respectively (in mm!) //(11,12 and 13,14 are set to values for a linear response, as from a new Ordela detector) realw[10] = getDetectorPixelXSize(fname) realw[11] = 10000 realw[12] = 0 realw[13] = getDetectorPixelYSize(fname) realw[14] = 10000 realw[15] = 0 // beam center X,Y on the detector (in units of pixel coordinates (1,N)) realw[16] = getBeamXPos(fname) realw[17] = getBeamYPos(fname) // sample to detector distance (meters) realw[18] = getSDD(fname) // detector physical width (right now assumes square...) (in cm) realw[20] = 65 // beam stop diameter (assumes circular) (in mm) realw[21] = getBSDiameter(fname) // source aperture diameter (mm) realw[23] = getSourceApertureDiam(fname) // sample aperture diameter (mm) realw[24] = getSampleApertureDiam(fname) // source aperture to sample aperture distance realw[25] = getSourceToSampleDist(fname) // wavelength (A) realw[26] = getWavelength(fname) // wavelength spread (FWHM) realw[27] = getWavelengthSpread(fname) // beam stop X-position (motor reading, approximate cm from zero position) // currently NCNR-specific use to identify transmission measurements // you return 0 realw[37] = 0 // the actual data array, dimensions are set as globals in // InitFacilityGlobals() NVAR XPix = root:myGlobals:gNPixelsX NVAR YPix = root:myGlobals:gNPixelsX Make/D/O/N=(XPix,YPix) $"root:RAW:data" WAVE data=$"root:RAW:data" // fill the data array with the detector values getDetectorData(fname,data) //keep a string with the filename in the RAW folder String/G root:RAW:fileList = textw[0] Return 0 End //**************** //main entry procedure for reading a "WORK.DIV" file //displays a quick image of the file, to check that it's correct //data is deposited in root:Packages:NIST:DIV data folder // // local, currently unused // // Proc ReadWork_DIV() String fname = PromptForPath("Select detector sensitivity file") ReadHeaderAndWork("DIV",fname) //puts what is read in work.div String waveStr = "root:Packages:NIST:DIV:data" // NewImage/F/K=1/S=2 $waveStr //this is an experimental IGOR operation // ModifyImage '' ctab= {*,*,YellowHot,0} //Display;AppendImage $waveStr //change the title string to WORK.DIV, rather than PLEXnnn_TST_asdfa garbage // String/G root:Packages:NIST:DIV:fileList = "WORK.DIV" ChangeDisplay("DIV") SetDataFolder root: //(redundant) End // Detector sensitivity files have the same header structure as RAW SANS data // as NCNR, just with a different data array (real, rather than integer data) // // So for your facility, make this reader specific to the format of whatever // file you use for a pixel-by-pixel division of the raw detector data // to correct for non-uniform sensitivities of the detector. This is typically a // measurement of water, plexiglas, or another uniform scattering sample. // // The data must be normalized to a mean value of 1 // // called from ProtocolAsPanel.ipf // // type is "DIV" on input Function ReadHeaderAndWork(type,fname) String type,fname //type is the desired folder to read the workfile to //this data will NOT be automatically displayed // gDataDisplayType is unchanged String cur_folder = type String curPath = "root:Packages:NIST:"+cur_folder SetDataFolder curPath //use the full path, so it will always work Variable refNum,integer,realval String sansfname,textstr Variable/G $(curPath + ":gIsLogScale") = 0 //initial state is linear, keep this in DIV folder Make/O/D/N=23 $(curPath + ":IntegersRead") Make/O/D/N=52 $(curPath + ":RealsRead") Make/O/T/N=11 $(curPath + ":TextRead") WAVE intw=$(curPath + ":IntegersRead") WAVE realw=$(curPath + ":RealsRead") WAVE/T textw=$(curPath + ":TextRead") // the actual data array, dimensions are set as globals in // InitFacilityGlobals() NVAR XPix = root:myGlobals:gNPixelsX NVAR YPix = root:myGlobals:gNPixelsX Make/O/D/N=(XPix,YPix) $(curPath + ":data") WAVE data = $(curPath + ":data") // (1) // fill in your reader for the header here so that intw, realw, and textW are filled in // ? possibly a duplication of the raw data reader //(2) // then fill in a reader for the data array that will DIVIDE your data // to get the corrected values. //keep a string with the filename in the DIV folder String/G $(curPath + ":fileList") = textw[0] //return the data folder to root SetDataFolder root: Return(0) End ///// ASC FORMAT READER ////// ///// FOR WORKFILE MATH PANEL ////// // //function to read in the ASC output of SANS reduction // currently the file has 20 header lines, followed by a single column // of 16384 values, Data is written by row, starting with Y=1 and X=(1->128) // //returns 0 if read was ok //returns 1 if there was an error // // called by WorkFileUtils.ipf // // // If the ASC data was generated by the NCNR data writer, then // NOTHING NEEDS TO BE CHANGED HERE // Function ReadASCData(fname,destPath) String fname, destPath //this function is for reading in ASCII data so put data in user-specified folder SetDataFolder "root:Packages:NIST:"+destPath NVAR pixelsX = root:myGlobals:gNPixelsX NVAR pixelsY = root:myGlobals:gNPixelsY Variable refNum=0,ii,p1,p2,tot,num=pixelsX,numHdrLines=20 String str="" //data is initially linear scale Variable/G :gIsLogScale=0 Make/O/T/N=(numHdrLines) hdrLines Make/O/D/N=(pixelsX*pixelsY) data //,linear_data //full filename and path is now passed in... //actually open the file // SetDataFolder destPath Open/R/Z refNum as fname // /Z flag means I must handle open errors if(refnum==0) //FNF error, get out DoAlert 0,"Could not find file: "+fname Close/A SetDataFolder root: return(1) endif if(V_flag!=0) DoAlert 0,"File open error: V_flag="+num2Str(V_Flag) Close/A SetDataFolder root: return(1) Endif // for(ii=0;ii