;+ ; NAME: ; ml_makeslitmap ; ; PURPOSE: ; Produces the slitmap file defining all correspondence between ; fiber location on the slit, on sky, and in bundles. Returns the ; slitmap, and can also stuff it into mangacore if desired. ; ; CALLING SEQUENCE: ; slitmap=ml_makeslitmap(plugfile, [plugdir=,slithdr=,slitdir=,/writeslitfile]) ; ; INPUTS: ; plugfile - Name of the plPlugMapM to be read ; ; OPTIONAL INPUTS: ; plugdir - Directory to look in for plugmap (defaults to mangacore) ; slithdr - Slitmap header information to return ; /writeslitfile - Write new slitmap to mangacore ; slitdir - Directory to write slitmap file to ; ; OUTPUTS: ; slitmap - Yanny .par structure MaNGA slitmap ; ; EXAMPLES: ; slitmap=ml_makeslitmap('plPlugMapM-7341-56691-01.par') ; ; BUGS: ; ; PROCEDURES CALLED: ; concat_dir() ; ml_getenv() ; ml_plategroup() ; findfile() ; yanny_readone() ; yanny_par() ; mlmatchmjd() ; mlreadbundlemap() ; fileandpath() ; mlcheckplugging() ; mlmatchplugholes() ; mlstrreplace() ; yanny_write() ; ml_fixplateholes ; tag_exist() ; ; REVISION HISTORY: ; v1.0: 23-Sep-2013 David R. Law (Dunlap Institute; drlaw@di.utoronto.ca) ; First written. ; 26-Sep-2013 Added tileId keyword from plugmap header to slitmap header ; 24-Oct-2013 Added psfmag information from plateHolesSorted ; 05-Feb-2014 Bug fixes based on real mapper results (D. Law) ; 16-Feb-2014 Added optional input of slitdir for DOS usage (B. Cherinka) ; 28-Mar-2014 Fixed output of reddeningMed vector in slit header (D. Law) ; 21-May-2014 Include racen, deccen info for all entries (D. Law) ; 14-Jul-2014 Added call to fix the plateHoles file if needed (D. Law) ; 17-Jul-2014 Made call to read plateholes anonymous (D. Law) ; 04-Nov-2014 Added manga_target3 bit (D. Law; dlaw@stsci.edu) ; 04-Dec-2014 Add sanity check that mapper didn't assign sky fibers ; to an ifu hole (D. Law; dlaw@stsci.edu) ; 29-Apr-2016 Add mangaredmed to slitmap header (D. Law) ; 11-Jul-2016 Add drilltemp to slitmap header (D. Law) ;- function ml_makeslitmap, plugfile, plugdir=plugdir, slithdr=slithdr, writeslitfile=writeslitfile, slitdir=slitdir on_error,0 compile_opt idl2 if size(plugfile,/type) ne 7 then splog, 'ERROR: plugfile must be of type string' ; Guess plateid from plugfile name ; Must have the format plPlugMapM-PLATE-MJD-VER.par plateid=(strsplit(plugfile,'-',/extract))[1] if (keyword_set(plugdir)) then plugdir=plugdir $ else plugdir=concat_dir(ml_getenv('MANGACORE_DIR'),'mapper/'+ml_plategroup(plateid)+'/'+plateid+'/') plgfile=plugdir+plugfile splog,'Reading plugmap from '+plgfile ; Check whether file exists junk=file_search(plgfile,count=ct) if (ct EQ 0) then message,'Failed to find plugmap: '+plgfile ; If it exists, read in the PLUGMAPOBJ structure plugmap=yanny_readone(plgfile,'PLUGMAPOBJ',hdr=plughdr) ; Define some key information from the plugmap header plateid=(yanny_par(plughdr, 'plateId'))[0] designid=(yanny_par(plughdr, 'designid'))[0] mjdscan=(yanny_par(plughdr, 'fscanMJD'))[0] cart=(yanny_par(plughdr, 'cartridgeId'))[0] reddeningMed=yanny_par(plughdr, 'reddeningMed') ;tile=(yanny_par(plughdr, 'tileId'))[0] hamin=(yanny_par(plughdr, 'haMin'))[0] hamax=(yanny_par(plughdr, 'haMax'))[0] ha=(yanny_par(plughdr, 'ha'))[0] racen=(yanny_par(plughdr, 'raCen'))[0] deccen=(yanny_par(plughdr, 'decCen'))[0] drilltemp=(yanny_par(plughdr, 'temp'))[0] ; Strip out only the lines with MANGA or MANGA_SINGLE information index=where((plugmap.holeType eq 'MANGA')or(plugmap.holeType eq 'MANGA_SINGLE')) plugmap=plugmap[index] ; Read prototype slitmap file slitdir0=concat_dir(ml_getenv('MANGACORE_DIR'),'slitmaps/00XX/') slitmapprototype=yanny_readone(slitdir0+'slitmap-0001-00001-1.par','SLITMAP',hdr=slithdr) ; Strip out all lines from header that don't start with '#' cline=where(strmid(slithdr,0,1) eq '#') slithdr=[slithdr[cline], ' '] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Find and read in the plateHolesSorted file ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; holedir=concat_dir(ml_getenv('MANGACORE_DIR'),'platedesign/plateholes/'+ml_plategroup(plateid)+'/') ; Convention from SDSS-III is to use leading zeroes... if (long(plateid) le 9999) then $ holefile=holedir+'plateHolesSorted-'+'00'+plateid+'.par' if (long(plateid) ge 10000) then $ holefile=holedir+'plateHolesSorted-'+'0'+plateid+'.par' ; Test for file existence if (~file_test(holefile)) then begin message,'WARNING- plateHolesSorted file '+holefile+' not found!' endif splog,'Reading plateHolesSorted file '+holefile ; Read it in (must be anonymous since structure has changed ; over the survey lifetime) plateholes=yanny_readone(holefile,'STRUCT1',/anon) ; Fix the plateholes file if necessary ml_fixplateholes,plateid,plateholes ; Filter to only the lines with MANGA or MANGA_SINGLE information plateholes=plateholes[where((strtrim(plateholes.holetype,2) eq 'MANGA')or(strtrim(plateholes.holetype,2) eq 'MANGA_SINGLE'))] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Find and read in the cartmap ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Find the appropriate cartmap ; cartstr is the 2-digit cart identifier cartstr=cart if (cart lt 10) then cartstr='0'+cart ; Search for all cartmaps for this cart number cartdir=concat_dir(ml_getenv('MANGACORE_DIR'),'cartmaps/') carttarget=cartdir+'cartmap-'+cartstr+'-' cartsearch=file_search(carttarget+'*') ; Figure out which of these has appropriate MJD ; (MJD closest to, but <= MJDscan) cartfile=ml_matchmjd(cartsearch,carttarget,long(mjdscan)) ; Test for file existence if (~file_test(cartfile)) then begin message,'WARNING- cartmap not found! Are you sure cart '+cartstr+' has MaNGA fibers??' endif ; And read it in cartmap=yanny_readone(cartfile,'CMAP',hdr=carthdr) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Assign cartmap information to the slitmap ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Define cartmapUQ, which is unique version of the cartmap with only ; one entry per v-groove block cartmapUQ=cartmap[uniq(cartmap.blockid)] nblocks=(size(cartmapUQ))[1] nfibers=fix(total(cartmapUQ.blocksize)) ; Make the new slitmap structure slitmap=replicate(slitmapprototype,nfibers) ; Assign fiberid from 1-nfibers for i=0,nfibers-1 do slitmap[i].fiberid=i+1 ; Loop over v-groove blocks assigning info starting from fiberid=1 ; Don't do frlPlug here- that's tricky, do it later when pulling ; metrology assignments fstart=1 for i=0,nblocks-1 do begin fstop=fstart+cartmapUQ[i].blocksize-1 index=where((slitmap.fiberid ge fstart)and(slitmap.fiberid le fstop)) slitmap[index].blockid=cartmapUQ[i].blockid slitmap[index].spectrographid=cartmapUQ[i].spectrographid slitmap[index].harType=cartmapUQ[i].harType slitmap[index].harblock=cartmapUQ[i].harblock slitmap[index].blocksize=cartmapUQ[i].blocksize slitmap[index].vpitch=cartmapUQ[i].vpitch slitmap[index].ifusize=cartmapUQ[i].ifusize slitmap[index].harName=cartmapUQ[i].harName ; Increment fiber counting fstart=fstop+1 endfor ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Pull information on fiber bundle metrology ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Loop over 'SINGLE' harnesses (i.e., those with one or fewer IFUs ; per v-groove block) assigning info cartmapSINGLE=cartmap[where(cartmap.harType eq 'SINGLE',nsingle)] for i=0,nsingle-1 do begin harname=cartmapSINGLE[i].harName ; Find and read the metrology file for this harness bundlemap=ml_readbundlemap(harname,mjdscan,metrfile=metrfile,/silent) ; Which v-groove block in the harness is it? harblock=cartmapSINGLE[i].harblock ; How many fibers in this v-groove block? blocksize=cartmapSINGLE[i].blocksize ; Which was the frlPlug? frlPlug=cartmapSINGLE[i].frlPlug ; Find all fibers in the slitmap corresponding to this harness and block working=where((slitmap.harName eq harname)and(slitmap.harblock eq harblock)) ; Find fibers in the metrology file corresponding to this block subbundle=bundlemap[where(bundlemap.harblock eq harblock)] ; Check that same number of fibers in slitmap as meant to be if (~(blocksize eq (size(working))[1])) then $ message,'CRITICAL failure- mismatched block sizes' ; Loop over fibers in the v-groove block assigning info from metro data slitmap[working].harblock=harblock slitmap[working].blocksize=blocksize slitmap[working].frlPlug=frlPlug for j=0,blocksize-1 do begin slitmap[working[j]].finblock=subbundle[j].finblock slitmap[working[j]].ifuinblock=subbundle[j].ifuinblock slitmap[working[j]].fibertype=subbundle[j].fibertype ; Define default holetype here, because can't rely on getting that ; info correctly from the plugmap if a fiber is unplugged if (slitmap[working[j]].fibertype eq 'SKY') then slitmap[working[j]].holetype='MANGA_SINGLE' if (slitmap[working[j]].fibertype eq 'IFU') then slitmap[working[j]].holetype='MANGA' slitmap[working[j]].fnum=subbundle[j].fnum slitmap[working[j]].gbu=subbundle[j].gbu ; If gbu set to 3, fiber was dead, consider it unplugged if (slitmap[working[j]].gbu eq 3) then slitmap[working[j]].plugstatus=1 slitmap[working[j]].frlCode=subbundle[j].frlCode slitmap[working[j]].xpmm=subbundle[j].xpmm slitmap[working[j]].ypmm=subbundle[j].ypmm endfor ; If it was the first v-groove block in a harness, then ; add the metrology file information to the slitmap header if (harblock eq 1) then $ slithdr=[slithdr, harname+' '+fileandpath(metrfile)] endfor ; Loop over 'MULTIPLE' harnesses (i.e., those with >1 IFU per v-groove ; block) assigning info cartmapMULTIPLE=cartmap[where(cartmap.harType eq 'MULTIPLE',nmultiple)] for i=0,nmultiple-1 do begin harname=cartmapMULTIPLE[i].harName ; Find and read the metrology file for this harness bundlemap=ml_readbundlemap(harname,mjdscan,metrfile=metrfile,/silent) ; Which v-groove block in the harness is it? harblock=cartmapMULTIPLE[i].harblock ; How many fibers in this v-groove block? blocksize=cartmapMULTIPLE[i].blocksize ; Which was the frlPlug? frlPlug=cartmapMULTIPLE[i].frlPlug ; Find all fibers in the slitmap corresponding to this harness working=where(slitmap.harName eq harname) slitmap[working].harblock=harblock slitmap[working].blocksize=blocksize for j=0,blocksize-1 do begin slitmap[working[j]].finblock=bundlemap[j].finblock slitmap[working[j]].ifuinblock=bundlemap[j].ifuinblock slitmap[working[j]].fibertype=bundlemap[j].fibertype ; Define default holetype here, because can't rely on getting that ; info correctly from the plugmap if a fiber is unplugged if (slitmap[working[j]].fibertype eq 'SKY') then slitmap[working[j]].holetype='MANGA_SINGLE' if (slitmap[working[j]].fibertype eq 'IFU') then slitmap[working[j]].holetype='MANGA' slitmap[working[j]].fnum=bundlemap[j].fnum slitmap[working[j]].gbu=bundlemap[j].gbu slitmap[working[j]].frlCode=bundlemap[j].frlCode slitmap[working[j]].xpmm=bundlemap[j].xpmm slitmap[working[j]].ypmm=bundlemap[j].ypmm endfor ; Redefine working to be the fibers in the slitmap corresponding ; both to this harness and to this ifuinblock ifuinblock=cartmapMULTIPLE[i].ifuinblock working=where((slitmap.harName eq harname)and(slitmap.ifuinblock eq ifuinblock)) ; Define frlPlug from this correspondence slitmap[working].frlPlug=cartmapMULTIPLE[i].frlPlug ; If it was the first ifuinblock, then ; add the metrology file information to the slitmap header if (ifuinblock eq 1) then $ slithdr=[slithdr, harname+' '+fileandpath(metrfile)] endfor ; Reset frlPlug=0 for all sky fibers working=where(slitmap.fibertype eq 'SKY') slitmap[working].frlPlug=0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Put the plugmap information in the slitmap ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; By default, assume all fibers unplugged (plugstatus=1) slitmap[*].plugstatus=1 nfplug=(size(plugmap))[1] ; Assign some information that is valid for the whole plate ; (cenra and cendec) slitmap[*].cenra=racen slitmap[*].cendec=deccen for i=0,nfplug-1 do begin ; If fiberid is negative, it wasn't plugged, assign default info ; plus some basic whole-plate information if (plugmap[i].fiberid lt 0) then begin endif ; Otherwise, assign real info if (plugmap[i].fiberid ge 1) then begin ; It corresponds to the line in the slitmap matched by fiberid slitline=where(slitmap.fiberid eq plugmap[i].fiberid) ; Sanity check- ensure that anything given this fiberid by the mapper ; is good in the metrology file! if (slitmap[slitline].gbu eq 0) then begin ; Fill in information from the plugmap slitmap[slitline].plugstatus=0 ;slitmap[slitline].holetype=plugmap[i].holetype slitmap[slitline].ra=plugmap[i].ra slitmap[slitline].dec=plugmap[i].dec slitmap[slitline].xFocal=plugmap[i].xFocal slitmap[slitline].yFocal=plugmap[i].yFocal ; Sanity check that what should be on spec1 really is on spec1 if (slitmap[slitline].spectrographid ne plugmap[i].spectrographId) then $ message,'MAJOR error: spectrograph id in cartmap and plugmap dont match!' ; Fill in information from plateHolesSorted file by matching xFocal,yFocal ; in plateHolesSorted file against plugmap file to determine line index index=ml_matchplugholes(plateholes,slitmap[slitline].xFocal,slitmap[slitline].yFocal) slitmap[slitline].targettype=plateholes[index].targettype slitmap[slitline].epoch=plateholes[index].epoch slitmap[slitline].manga_target1=plateholes[index].manga_target1 slitmap[slitline].manga_target2=plateholes[index].manga_target2 ; manga_target3 column didn't exist in early plates ; Check for existence before copying to slitmap ; If it doesn't exist, use 0 if tag_exist(plateholes,'manga_target3') then slitmap[slitline].manga_target3=plateholes[index].manga_target3 $ else slitmap[slitline].manga_target3=0 slitmap[slitline].mangaID=plateholes[index].mangaID slitmap[slitline].ifuDesign=plateholes[index].ifuDesign slitmap[slitline].psfmag=plateholes[index].psfmag ; Sanity check that we haven't assigned any MANGA_SINGLE fibers to IFUs ; (e.g., due to mapper errors like on Dec 4 2014). ; If so, bomb out 'coz the plugmap is bad if ((strtrim(slitmap[slitline].holetype,2) eq 'MANGA_SINGLE')and(slitmap[slitline].ifudesign ne 0)) then begin splog,'WARNING- Bad plugmap '+plugfile + '!' message,'Mapper has assigned a sky fiber to an IFU hole!!' endif endif endif endfor ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Kludge for dead fibers in an IFU that aren't picked up by ; the mapper. Give even dead fibers correct ifudesign and position ; information as it IS known. ; Assume that all ifu fibers work unless metrology file specifies ; otherwise. Loop through all IFUs- see what the plug information is ; for 50% of the fibers, apply this to any that maper didn't pick up. ; Apply to fibers where gbu=0, plugstatus=1, fibertype=IFU ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Where are the ifu fibers? theifufibers=where(slitmap.fibertype eq 'IFU',nifufibers) ; Cull slitmap to only those ifu fibers slitmap_ifus=slitmap[theifufibers] ; Figure out unique names of frlplug uniqueifus=slitmap_ifus[uniq(slitmap_ifus.frlplug)].frlplug nunique=n_elements(uniqueifus) ; Loop over all unique frlplug values for i=0,nunique-1 do begin ; Which lines in the slitmap correspond to this frlplug? slitlines=where(slitmap.frlplug eq uniqueifus[i]) ; What is currently listed for the ifudesign of these lines? desnames=slitmap[slitlines].ifudesign ; If there was one good plugged fiber in the ifu, then all of them ; should be in that hole even if the mapper didn't see them ; Pick one that was assigned a non-negative value for ifudesign temp=where(desnames gt 0,ngood) if (ngood ne 0) then begin goodline=slitlines[temp[0]] ; Assign all key values from that line to all other lines slitmap[slitlines].ra=slitmap[goodline].ra slitmap[slitlines].dec=slitmap[goodline].dec slitmap[slitlines].xFocal=slitmap[goodline].xFocal slitmap[slitlines].yFocal=slitmap[goodline].yFocal slitmap[slitlines].targettype=slitmap[goodline].targettype slitmap[slitlines].epoch=slitmap[goodline].epoch slitmap[slitlines].manga_target1=slitmap[goodline].manga_target1 slitmap[slitlines].manga_target2=slitmap[goodline].manga_target2 slitmap[slitlines].manga_target3=slitmap[goodline].manga_target3 slitmap[slitlines].mangaID=slitmap[goodline].mangaID slitmap[slitlines].ifuDesign=slitmap[goodline].ifuDesign slitmap[slitlines].psfmag=slitmap[goodline].psfmag slitmap[slitlines].plugstatus=slitmap[goodline].plugstatus endif endfor ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check if plugging was done correctly ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Where are the ifu fibers? theifufibers=where(slitmap.fibertype eq 'IFU',nifufibers) ; Cull slitmap to only those ifu fibers slitmap_ifus=slitmap[theifufibers] ; Uniquely plugged ifus uniqplug=slitmap_ifus[uniq(slitmap_ifus.frlPlug)] fplug=uniqplug.frlPlug ides=uniqplug.ifuDesign ; Function ml_checkplugging tests frlPlug vs ifuDesign to see if ; it matches what it's supposed to nplugerr=ml_checkplugging(fplug,ides) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check that no IFU fibers have ifuDesign=0 (are in a sky hole) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; index=where((slitmap.holetype eq 'MANGA')and(slitmap.ifudesign eq 0),nindex) if (nindex ne 0) then $ message, 'FATAL error creating slitmap, bad plugmap!' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Check that all ifus have the correct total number of fibers ; check using ifuDesign since this is what we kludged above ; for missing fibers ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Where are the plugged ifu fibers? theifufibers=where((slitmap.fibertype eq 'IFU')and(slitmap.plugstatus eq 0),nifufibers) ; Cull slitmap to only those ifu fibers slitmap_ifus=slitmap[theifufibers] ; Figure out unique names of ifuDesign uniqueifus=slitmap_ifus[uniq(slitmap_ifus.ifudesign)].ifudesign nunique=n_elements(uniqueifus) ; Loop over all unique frlplug values for i=0,nunique-1 do begin ; Which lines in the ENTIRE slitmap correspond to this ifudesign? slitlines=where(slitmap.ifudesign eq uniqueifus[i],nlines) ; Check that nlines matches slitmap.ifusize for *every* fiber ; just to be sure. We should never fail out here given checks ; already made, but you never know... for j=0,nlines-1 do begin if (slitmap[slitlines[j]].ifusize ne nlines) then $ message, 'FATAL error creating slitmap, bad plugmap!' endfor endfor ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Do not use reddenmed from plugmap- this is for APOGEE holes ; Calculate our own mangaredmed from all MaNGA science IFUs ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Select all IFU fibers not in calibration minibundles index=where((strtrim(slitmap.fibertype,2) eq 'IFU')and(strtrim(slitmap.hartype,2) eq 'SINGLE'),nindex) ; Cull slitmap to only those ifu fibers slitmap_ifus=slitmap[index] ; Figure out an index to unique names of ifuDesign uqindex=uniq(slitmap_ifus.ifudesign) nunique=n_elements(uqindex) ; Vector of E(B-V) across the science IFUs ebv=fltarr(nunique) ; Loop over all unique ifuDesign values for i=0,nunique-1 do begin ; Galactic longitude/latitude for this IFU glactc,slitmap_ifus[uqindex[i]].ra,slitmap_ifus[uqindex[i]].dec,2000.,glon,glat,1,/degree ; Convert glon/glat to dust e(b-v) with a safety to ensure ebv>0 ebv[i]=dust_getval(glon,glat,/interp) > 0 endfor ; Median E(B-V) ebvmed=median(ebv) ; Corresponding griz reddening values redvals=[3.303, 2.285, 1.698, 1.263]##ebvmed ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Add info to the slitmap header and write it out ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; slitdir=(n_elements(slitdir) eq 0) ? concat_dir(ml_getenv('MANGACORE_DIR'),'slitmaps/'+ml_plategroup(plateid)+'/'+plateid+'/') : slitdir ; Add info to the slitmap header slithdr=[slithdr, 'plate '+plateid] slithdr=[slithdr, 'designid '+designid] slithdr=[slithdr, 'mjdscan '+mjdscan] slithdr=[slithdr, 'cart '+cart] ;slithdr=[slithdr, 'tile '+tile] slithdr=[slithdr, 'hamin '+hamin] slithdr=[slithdr, 'hamax '+hamax] slithdr=[slithdr, 'ha '+ha] slithdr=[slithdr, 'racen '+racen] slithdr=[slithdr, 'deccen '+deccen] slithdr=[slithdr, 'drilltemp '+drilltemp] slithdr=[slithdr, 'plugmap '+plugfile] redmed='' for i=0,n_elements(reddeningMed)-1 do redmed=redmed+' '+reddeningMed[i] ; reddeningmed is for APOGEE holes, but keep for backwards compatibility slithdr=[slithdr, 'reddeningmed '+redmed] mangaredmed='' for i=0,n_elements(redvals)-1 do mangaredmed=mangaredmed+' '+string(redvals[i]) slithdr=[slithdr, 'mangaredmed '+mangaredmed] slithdr=[slithdr, 'cartmap '+fileandpath(cartfile)] slithdr=[slithdr, 'plateholes '+fileandpath(holefile)] ; Set the slitmap name to match plugmap slitfile=ml_strreplace(plugfile,'plPlugMapM','slitmap') if (keyword_set(writeslitfile)) then begin spawn, 'mkdir -p ' + slitdir yanny_write,slitdir+slitfile,ptr_new(slitmap),hdr=slithdr endif return,slitmap end