// Spectra Profile // Analyze Rainbow Optics diffraction grating spectra. // The spectra is horziontal and to the right side of the zero mode // The Spectrum Vertical Offset is for adjusting a few pixels slant horziontal (in my case 3 pixels clockwise slant.) // This default path is C:\Spectra\ // The defaults are setup for V IY Dra in KUV18217+6419c.fit file. // This ImageJ macro was development with ImageJ 1.43u // Max profile length is 590 pixels. // // // Clear and dark skies, // David Haworth // http://www.stargazing.net/david userSelect = false ; // true for image that is opened, false for automatically opening an image // First Menu Defaults for V IY Dra in KUV18217+6419c.fit objectName = "V_IY_Dra"; path = "C:\\Spectra\\"; fileName = "KUV18217+6419c.fit"; xCentroid = 26; yCentroid = 273; selectionXwidth = 590; plotStartpixel= 162; selectionHeight = 6; selectionHeightOffset = 3; showHalpha = true; showHbeta = true; showHgamma = true; showHdelta = false; showHepsilon = false; showHzeta = false; showO_III = false; showRedshiftElements = false; nedRedshift = 0; saveCalibratedSpectrumTable = true; showProcessSpectrum = true; showSpectrumSurfacePlot = true; fixWindowLocation = true; changeCalValues = false; // First Menu Defaults End // Second Menu Defaults Change Spectrum Calibration Values gratingFilter ="RO200"; gratingDisToCCD = 0.01832719265135; pixelSize = 0.0000068; useLinearCal = true; specAdjustB = -2.5982; specAdjustHa = 357; specAdjustHg = 18.3653; specAdjustDelta =136; notCalImage = false; imageBias = 100; bgXOffSet=70; bgYOffSet=-5; bgWidth=90; bgHeight=10; // Second Menu Defaults End // Other variables bgX=0; bgY=0; bgCount=0; bgMean=0; bgMin=0; bgMax=0; bgStd=0; bgHist=0; // Other constants angstroms = 10000000000; gratingRes = 0.000005; imageZoom = 1; requires("1.43u"); run("Appearance...", " open antialiased menu=14"); // Open images at 100% versionNum = 2.7; dateTime = dateTimeStr(); run("Input/Output...", "jpeg=98 gif=-1 file=.xls copy"); if(userSelect == true) { run("Measure"); xCentroid = getResult("X"); yCentroid = getResult("Y"); } // Show First Menu Dialog.create("Spectrum Calibration V"+versionNum+" Macro"); if(userSelect == false) { Dialog.addMessage("Defaut Values are for V IY Dra in KUV18217+6419c.fit"); Dialog.addString("Object Name", objectName,15); Dialog.addString("Directory_Path_for_the_Below_Image_File", path,15); Dialog.addString("Image_Fit_File", fileName,15); } else { Dialog.addString("Object Name", objectName,15);} Dialog.addNumber("Zero_Mode_X_Centroid", xCentroid); Dialog.addNumber("Zero_Mode_Y_Centroid", yCentroid); Dialog.addNumber("X_Centroid_to_End_of_Spectrum_Width_Max_590", selectionXwidth); Dialog.addNumber("Spectrum_Plot_Start", plotStartpixel); Dialog.addNumber("Spectrum_Selection_Height", selectionHeight); Dialog.addNumber("Spectrum_Selection_Vertical_Offset", selectionHeightOffset); Dialog.addCheckbox("Show_H-alpha_Emission Line", showHalpha); Dialog.addCheckbox("Show_H-beta_Emission_Line", showHbeta); Dialog.addCheckbox("Show_H-gamma_Emission_Line", showHgamma); Dialog.addCheckbox("Show_H-delta_Emission_Line", showHdelta); Dialog.addCheckbox("Show_H-epsilon_Emission_Line", showHepsilon); Dialog.addCheckbox("Show_H-zeta_Emission_Line", showHzeta); Dialog.addCheckbox("Show _O[III]_Emission_Line", showO_III); Dialog.addCheckbox("Show_Emission_Lines_with_Redshift", showRedshiftElements); Dialog.addNumber("Redshift", nedRedshift); Dialog.addCheckbox("Save_Spectrum_Table", saveCalibratedSpectrumTable); Dialog.addCheckbox("Show_Process_Spectrum", showProcessSpectrum); Dialog.addCheckbox("Show_Spectrum_Surface_Plot", showSpectrumSurfacePlot); Dialog.addCheckbox("Fixed_Windows_Locations", fixWindowLocation); Dialog.addCheckbox("Change_Spectrum_Calibration Values", changeCalValues); Dialog.show(); // End of Show First Menu // Get First Menu Values objectName = Dialog.getString(); if(userSelect == false) { path = Dialog.getString(); fileName = Dialog.getString(); } xCentroid = Dialog.getNumber(); yCentroid = Dialog.getNumber(); selectionXwidth = Dialog.getNumber(); plotStartpixel = Dialog.getNumber(); selectionHeight = Dialog.getNumber(); selectionHeightOffset = Dialog.getNumber(); showHalpha = Dialog.getCheckbox(); showHbeta = Dialog.getCheckbox(); showHgamma = Dialog.getCheckbox(); showHdelta = Dialog.getCheckbox(); showHepsilon = Dialog.getCheckbox(); showHzeta = Dialog.getCheckbox(); showO_III = Dialog.getCheckbox(); showRedshiftElements = Dialog.getCheckbox(); nedRedshift = Dialog.getNumber(); saveCalibratedSpectrumTable = Dialog.getCheckbox(); showProcessSpectrum = Dialog.getCheckbox(); showSpectrumSurfacePlot = Dialog.getCheckbox(); fixWindowLocation = Dialog.getCheckbox(); changeCalValues = Dialog.getCheckbox(); // End of Get First Menu Values // Second Menu if(changeCalValues == true){ // Show Second Menu Dialog.create("Change Spectrum Calibration Values"); Dialog.addChoice("Grating_Filter", newArray("RO200", "SA100"), gratingFilter); Dialog.addNumber("Grating_Distance_to_CCD_in_mm", gratingDisToCCD*1000); Dialog.addNumber("CCD_Pixel_Size_in_Microns", pixelSize*1000000); Dialog.addMessage("Linear Calibration Values"); Dialog.addCheckbox("Linear_Calibration", useLinearCal); Dialog.addNumber("Angrstoms_to_Adjust_at_H-alpha", specAdjustB); Dialog.addNumber("H-alpha_Pixel", specAdjustHa); Dialog.addNumber("Angstroms_to_Adjust_at_H-gamma", specAdjustHg); Dialog.addNumber("Number_of_Pixels_Between_H-a_and_to_H-g", specAdjustDelta); Dialog.addCheckbox("No_Dark_Calibration", notCalImage); Dialog.addNumber("Image_Bias", imageBias); Dialog.addMessage("Background Selection for S/N"); Dialog.addNumber("X_Offset_from_Zero_Mode_X_Centroid", bgXOffSet); Dialog.addNumber("Y_Offset_from_Zero_Mode_Y_Centroid", bgYOffSet); Dialog.addNumber("Selection_Width", bgWidth); Dialog.addNumber("Selection_Height", bgHeight); Dialog.show(); // Show Second Menu // Get Second Menu Values gratingFilter = Dialog.getChoice(); gratingDisToCCD = Dialog.getNumber()/1000; pixelSize = Dialog.getNumber()/1000000; useLinearCal = Dialog.getCheckbox(); specAdjustB = Dialog.getNumber(); specAdjustHa = Dialog.getNumber(); specAdjustHg = Dialog.getNumber(); specAdjustDelta =Dialog.getNumber(); notCalImage = Dialog.getCheckbox(); imageBias =Dialog.getNumber(); bgXOffSet=Dialog.getNumber(); bgYOffSet=Dialog.getNumber(); bgWidth=Dialog.getNumber(); bgHeight=Dialog.getNumber(); // End of Get Second Menu Values } if(useLinearCal == false){ specAdjustB = 0; specAdjustHa = 0; specAdjustHg = 0; specAdjustDelta =1; } // Add File.separator to path if missing if(endsWith(path, File.separator)== false) path=path+File.separator; analyzeDir = path+objectName+"_"+dateTime+File.separator; File.makeDirectory(analyzeDir); fileNameSave = objectName+"_"+dateTime; pathFileNameSave = analyzeDir+fileNameSave; selectionX = xCentroid; selectionY = yCentroid; if(gratingFilter == "SA100") gratingRes = gratingRes*2; angstromsMin = sin(atan(pixelSize*(plotStartpixel)/gratingDisToCCD))*gratingRes*angstroms; angstromsMax = sin(atan(pixelSize*(selectionXwidth)/gratingDisToCCD))*gratingRes*angstroms; // Close Log and Profile window if (isOpen("Log")) { selectWindow("Log"); run("Close");} if (isOpen("Profile")) {selectWindow("Profile"); run("Close");} if(userSelect == false) { // Open file, adjust black point to min-10 and white point min+60 open(path+fileName); run("Flip Vertically"); } imageZoom = getZoom; centroidPixelValue= getPixel(xCentroid, yCentroid); if(bitDepth()!=32) run("32-bit"); if((getWidth-xCentroid) < selectionXwidth) selectionXwidth = (getWidth-xCentroid); saveAs("FITS", pathFileNameSave); run("Set Measurements...", " min centroid redirect=None decimal=4"); run("Measure"); getRawStatistics(count, mean, min, max, std, hist); run("Brightness/Contrast..."); setMinAndMax(min-10, min+60); // Selection and get profile selectWindow(fileNameSave+".fits"); makeRectangle(xCentroid-10, yCentroid-10, 20, 20); run("Measure"); xCentroidMeas = getResult("X"); yCentroidMeas = getResult("Y"); // Background Measurements bgX=selectionX+bgXOffSet; bgY=selectionY+bgYOffSet; specTitle3 = getTitle; makeRectangle(bgX, bgY, bgWidth, bgHeight); getRawStatistics(bgCount, bgMean, bgMin, bgMax, bgStd, bgHist); run("Brightness/Contrast..."); setMinAndMax(bgMin-10, bgMin+60); // Remove image bias from background mean, minimum and maximum. if(notCalImage == true) { bgMean = bgMean - imageBias; bgMin = bgMin - imageBias; bgMax = bgMax - imageBias; } run("Capture Image"); saveAs("Tiff", pathFileNameSave+"BgSelection.tif"); bgXCrop=selectionX-30; bgHeightCrop=bgHeight+32; bgYCrop=bgY; bgWidthCrop=selectionXwidth+30; makeRectangle(bgXCrop*imageZoom, (bgYCrop-(bgHeightCrop/2))*imageZoom, bgWidthCrop*imageZoom, bgHeightCrop*imageZoom); run("Crop"); saveAs("Jpeg", pathFileNameSave+"BgSelectionCrop.jpg"); if(fixWindowLocation == true) setLocation(650,700); selectWindow(specTitle3); // Spectrums Measurements makeRectangle(selectionX, selectionY-(selectionHeight/2)+selectionHeightOffset, selectionXwidth, selectionHeight); profile = getProfile(); // Create spectrum tables if(saveCalibratedSpectrumTable ==true) spec_max = createSpecTables (profile, plotStartpixel, pixelSize, gratingDisToCCD, gratingRes, angstroms, specAdjustB, specAdjustHa, specAdjustHg, specAdjustDelta, pathFileNameSave); // Plot spectrum profile starting at about 3,000 angstroms maxProfileSize = selectionXwidth-plotStartpixel; if(maxProfileSize>433) { maxProfileSize=433; angstromsMax = ((sin(atan(pixelSize*(plotStartpixel+maxProfileSize)/gratingDisToCCD))*gratingRes*angstroms)+specAdjustB)+((specAdjustHa-maxProfileSize)*specAdjustHg/specAdjustDelta); } makeRectangle(selectionX+plotStartpixel, selectionY-(selectionHeight/2)+selectionHeightOffset, maxProfileSize, selectionHeight); profile = getProfile(); xValues = getProfile(); spec_min =profile[0]; for (i=0; i profile[i]) spec_min = profile[i] ; spec_max =profile[0]; for (i=0; i profile[i]) spec_min = profile[i] ; spec_max =profile[0]; for (i=plotStartpixel; i profile[i]) spec_min = profile[i] ; spec_max =profile[plotStartpixel]; for (i=plotStartpixel; i (profile.length-1)) x1 = profile.length-1; else x1 = (x/3)+1; setPixel(x, y, profile8bit[x/3]); setPixel((x+1), y, (profile8bit[x/3]+(profile8bit[x1]-profile8bit[x/3])/3)); setPixel((x+2), y, (profile8bit[x/3]+(profile8bit[x1]-profile8bit[x/3])*2/3)); } } selectWindow("Spectrum3X"); setMinAndMax(0, 255); run("8-bit"); saveAs("Jpeg", pathFileNameSave+"Band3X.jpg"); saveAs("Tiff", pathFileNameSave+"Band3X.tif"); if(fixWindowLocation == true) setLocation(60,0); return specBandTitle; } // ********************************************************************************************************************************* // Create 3-D surface plot of spectrum function plotSpectrum (fileNameSave) { if (isOpen("Surface Plot")) {selectWindow("Surface Plot"); run("Close");} selectWindow(fileNameSave+".fits"); makeRectangle(selectionX+plotStartpixel, selectionY-(selectionHeight/2)+selectionHeightOffset, maxProfileSize, selectionHeight); run("Measure"); getRawStatistics(count, mean, min, max, std, hist); run("Brightness/Contrast..."); setMinAndMax(min-10, max); selectWindow(fileNameSave+".fits"); run("Surface Plot...", "polygon=100 shade draw_axis fill one smooth"); if(fixWindowLocation == true) setLocation(0,300); run("Capture Image"); saveAs("Jpeg", pathFileNameSave+"Surface.jpg"); saveAs("Tiff", pathFileNameSave+"Surface.tif"); run("Close"); } // ********************************************************************************************************************************* // Draw selection, crop image and save it function cropImageWithSelection (pathFileNameSave, fileNameSave) { selectWindow(fileNameSave+".fits"); run("Select None"); run("Duplicate...", "title=copy.fits"); setColor(65535); drawRect(selectionX+plotStartpixel-1, selectionY-(selectionHeight/2)+selectionHeightOffset-1, maxProfileSize+2, selectionHeight+2); run("Select None"); makeRectangle(selectionX-20, selectionY-20, selectionXwidth+40, selectionHeight+40); setPixel(xCentroid, yCentroid, 0); run("Crop"); if(fixWindowLocation == true) setLocation(650,600); saveAs("FITS", pathFileNameSave+"CropWithSelection"); run("Capture Image"); saveAs("Jpeg", pathFileNameSave+"CropWithSelection.jpg"); saveAs("Tiff", pathFileNameSave+"CropWithSelection.tif"); run("Close"); } // ********************************************************************************************************************************* // Crop image and save it function cropImage (pathFileNameSave, fileNameSave, specBandTitle) { selectWindow(fileNameSave+".fits"); run("Select None"); makeRectangle(selectionX-20, selectionY-10, selectionXwidth+40, selectionHeight+60); run("Crop"); saveAs("FITS", pathFileNameSave+"Crop"); specTitle2 = getTitle; run("Capture Image"); saveAs("Jpeg", pathFileNameSave+"Crop.jpg"); saveAs("Tiff", pathFileNameSave+"Crop.tif"); specTitle = getTitle; selectWindow(specBandTitle); run("Select All"); run("Copy"); run("Close"); setPasteMode("Transparent-zero"); selectWindow(specTitle); run("Paste"); makeRectangle(0, 0, getWidth, getHeight-10); run("Crop"); saveAs("Jpeg", pathFileNameSave+"SpecMerge.jpg"); saveAs("Tiff", pathFileNameSave+"SpecMerge.tif"); if(fixWindowLocation == true) setLocation(650,500); selectWindow(specTitle2); run("Close"); } // ********************************************************************************************************************************* // Save analysis setup info in Log function saveInfo (pathFileNameSave, fileNameSave) { print("Spectra Profile Version ", versionNum); print("Object Name: ", objectName); print("Source File Name: ", fileName); print("Save Files Directory Path: ", analyzeDir); print("Save file name: "+ fileNameSave+".fits"); print("Image Zoom: ", imageZoom); print(fileNameSave+"CropWithSelection.fits Image Width: "+ getWidth +" pixels"); print(fileNameSave+"CropWithSelection.fits Image Width: "+ getHeight +" pixels"); print(" "); print("Zero Mode X Centroid Entered: "+ xCentroid+" pixels, Measured: "+xCentroidMeas+" pixels"); print("Zero Mode Y Centroid Entered: "+ yCentroid+" pixels, Measured: "+yCentroidMeas+" pixels"); print("Pixel Value at Centroid: "+ centroidPixelValue+" ADU"); print(" "); print("Zero Mode Spectrum Width: "+ selectionXwidth +" pixels"); print("Spectrum Selection Plot Start: "+ plotStartpixel +" pixels"); print("Spectrum Selection Vertical Height: "+ selectionHeight+" pixels"); print("Spectrum Selection Vertical Offset: "+ selectionHeightOffset+" pixels"); print("Zero Mode Spectrum Selection X: "+ selectionX+" pixels"); print("Zero Mode Spectrum Selection Y: "+ selectionY-(selectionHeight/2)+selectionHeightOffset+" pixels"); print(" "); print("Spectrum Plot Selection X: "+ selectionX+plotStartpixel+" pixels"); print("Spectrum Plot Selection Y: "+ selectionY-(selectionHeight/2)+selectionHeightOffset+" pixels"); print("Spectrum Plot Selection Width: "+ selectionXwidth-plotStartpixel+" pixels"); print("Spectrum Plot Selection Start: "+ plotStartpixel+" pixels"); print(" "); print("Spectrum Plot Selection Start: "+ angstromsMin+" angstroms"); print("Spectrum Plot Selection End: "+ angstromsMax+" angstroms"); print("Spectrum Plot Average: "+ (angstromsMax-angstromsMin)/(selectionXwidth-plotStartpixel)+" angstroms/pixel"); print(" "); print("Spectrum Plot Maximum: "+ spec_min+" ADU"); print("Spectrum Plot Minimum: "+ spec_max+" ADU"); print(" "); print("Grating Distance to CCD is "+ gratingDisToCCD*1000+" mm"); print("CCD pixel size is "+ pixelSize*1000000+" microns"); print(" "); if(useLinearCal == true) print("Linear Calibration On"); else print("Linear Calibration Off"); print("Spectrum Offset", specAdjustB); print("H-alpha Pixel", specAdjustHa); print("Number of A to Adjust at_H-gamma", specAdjustHg); print("Number of Pixels to H-gamma", specAdjustDelta); print(" "); print("Non linear spectrum adjustment, Halpha angstroms offset: "+ specAdjustB+" angstroms"); print("Non linear spectrum adjustment, Halpha pixel position "+ specAdjustHa+" pixels"); print("Non linear spectrum adjustment, Hgamma angstroms offset: "+ specAdjustHg+" angstroms"); print("Non linear spectrum adjustment, Hgamma to Halpha a pixel offset: "+ specAdjustDelta+" pixels"); print(" "); print("Redshift z is "+ nedRedshift); print("Halpha ("+h_alpha+" angstroms) at "+nedRedshift+" redshift is "+ h_alphaAtRedshft + " angstroms"); print("Hbeta ("+ h_beta+" angstroms) at "+nedRedshift+" redshift is "+ h_betaAtRedshft + " angstroms"); print("Hgamma ("+h_gamma+" angstroms) at "+nedRedshift+" redshift is "+ h_gammaAtRedshft + " angstroms"); print("Hdelta ("+h_delta+" angstroms) at "+nedRedshift+" redshift is "+ h_deltaAtRedshft + " angstroms"); print("Hepsilon ("+h_epsilon+" angstroms) at "+nedRedshift+" redshift is "+ h_epsilonAtRedshft + " angstroms"); print("Hzeta ("+h_zeta+" angstroms) at "+nedRedshift+" redshift is "+ h_zetaAtRedshft + " angstroms"); print("O[III] ("+o_III+" angstroms) at "+nedRedshift+" redshift is "+ o_IIIAtRedshft + " angstroms"); print(" "); if (saveCalibratedSpectrumTable== true) print("Save Calibrated Spectrum Table"); if (showProcessSpectrum == true) print("Show Process Spectrum"); if (showSpectrumSurfacePlot == true)print("Show Spectrum Surface Plot"); if (showRedshiftElements == true)print("Show Redshft Elements"); print(" "); print("Background Selection Top Left X, Y: "+ bgX+", "+bgY); print("Background Selection Width: "+ bgWidth); print("Background Selection Height: "+ bgHeight); print("BackgroundSelection Bottom Right X, Y: "+ (bgX+bgWidth)+", "+bgY+(bgHeight)); print(" "); print("Background Count: "+ bgCount); print("Background Mean: "+ bgMean); print("Background Minimum: "+ bgMin); print("Background Maximum: "+ bgMax); print("Background Standard Deviation: "+ bgStd); print("Background Mean/Standard Deviation: "+ bgMean/bgStd); print("Spectrum Maximum: "+ spec_max); print("(Spectrum Maximum Signal - Background Mean)/(Background Standard Deviation) = Spectrum to Noise Ratio: "+ (spec_max-bgMean)/bgStd); print("End"); selectWindow("Log"); saveAs("Text", pathFileNameSave+"Log.txt"); run("Close"); } // Macro End ****************************************************************************************************************** ound mean:", imageBias); } else print("Image was dark calibrated"); print(" "); print("Background Count: ", bgCount); print("Background Minimum: ", bgMin); print("Background Maximum: ", bgMax); print("Background Mean: ", bgMean); print("Background Standard Deviation: ", bgStd); print("Background Mean/Standard Deviation: ", bgMean/bgStd); if(notCalImage == true) { print("Spectrum Maximum: ", spec_max-imageBias); print("Spectrum Maximum-Background Mean: ", spec_max-imageBias-bgMean); print("(Spectrum Maximum Signal - Background Mean)/(Background Standard Deviation) = Spectrum to Noise Ratio: "+ (spec_max-imageBias-bgMean)/bgStd); } else { print("Spectrum Maximum: ", spec_max); print("Spectrum Maximum-Background Mean: ", spec_max-bgMean); print("(Spectrum Maximum Signal - Background Mean)/(Background Standard Deviation) = Spectrum to Noise Ratio: "+ (spec_max-bgMean)/bgStd); } print("End"); selectWindow("Log"); saveAs("Text", pathFileNameSave+"Log.txt"); run("Close"); } // Macro End ******************************************************************************************************************