diff --git a/NamelistTemplates/EMEBSD.template b/NamelistTemplates/EMEBSD.template index 5c545a12..74dde416 100644 --- a/NamelistTemplates/EMEBSD.template +++ b/NamelistTemplates/EMEBSD.template @@ -20,6 +20,10 @@ energymax = 20.0, ! include a realistic intensity background or not ... includebackground = 'y', +! prefix of filename for individual pattern output (relative to EMdatapathname) +! this assumes that bitdepth below is set to 8bit; otherwise no images will be written. +! [Warning: operating systems typically don't like folders with 100,000 files or more...] + tiff_prefix = 'undefined', ! name of angle file (euler angles or quaternions); path relative to EMdatapathname anglefile = 'testeuler.txt', ! does this file have only orientations ('orientations') or does it also have pattern center and deformation tensor ('orpcdef') diff --git a/Source/EMOpenCLLib/Indexingmod.f90 b/Source/EMOpenCLLib/Indexingmod.f90 index 0e27d638..1aebf0b3 100644 --- a/Source/EMOpenCLLib/Indexingmod.f90 +++ b/Source/EMOpenCLLib/Indexingmod.f90 @@ -315,12 +315,22 @@ END SUBROUTINE ProgCallBackTypeErrorDIdriver ! intercept the case where the exptnumsx/y parameters are set to zero, but ! numsx/y are not... -if (dinl%exptnumsx.eq.0) dinl%exptnumsx = dinl%numsx -if (dinl%exptnumsy.eq.0) dinl%exptnumsy = dinl%numsy - +! +! this if statement is a consequence of an error discovered on 08/13/24 that only +! affects the Binary inputtype ... +if (trim(dinl%inputtype).eq.'Binary') then + if (dinl%exptnumsx.eq.0) dinl%exptnumsx = dinl%numsx/dinl%binning + if (dinl%exptnumsy.eq.0) dinl%exptnumsy = dinl%numsy/dinl%binning ! binned pattern array size for experimental patterns -binx = dinl%exptnumsx/dinl%binning -biny = dinl%exptnumsy/dinl%binning + binx = dinl%exptnumsx + biny = dinl%exptnumsy +else + if (dinl%exptnumsx.eq.0) dinl%exptnumsx = dinl%numsx + if (dinl%exptnumsy.eq.0) dinl%exptnumsy = dinl%numsy +! binned pattern array size for experimental patterns + binx = dinl%exptnumsx/dinl%binning + biny = dinl%exptnumsy/dinl%binning +end if bindx = 1.0/float(dinl%binning)**2 ! we also force the dictionary patterns to have this size dinl%numsx = binx @@ -347,9 +357,9 @@ END SUBROUTINE ProgCallBackTypeErrorDIdriver ! and then generate the detector arrays enl%numsx = dinl%numsx enl%numsy = dinl%numsy - enl%xpc = dinl%xpc - enl%ypc = dinl%ypc - enl%delta = dinl%delta + enl%xpc = dinl%xpc/dinl%binning + enl%ypc = dinl%ypc/dinl%binning + enl%delta = dinl%delta*dinl%binning enl%thetac = dinl%thetac enl%L = dinl%L enl%energymin = dinl%energymin diff --git a/Source/EMsoftHDFLib/NameListHDFwriters.f90 b/Source/EMsoftHDFLib/NameListHDFwriters.f90 index d920d4de..eec7d8c3 100644 --- a/Source/EMsoftHDFLib/NameListHDFwriters.f90 +++ b/Source/EMsoftHDFLib/NameListHDFwriters.f90 @@ -2911,6 +2911,11 @@ recursive subroutine HDFwriteEBSDNameList(HDF_head, enl) hdferr = HDF_writeDatasetStringArray(dataset, line2, 1, HDF_head) if (hdferr.ne.0) call HDF_handleError(hdferr,'HDFwriteEBSDNameList: unable to create masterfile dataset',.TRUE.) +dataset = trim(enl%tiff_prefix) +line2(1) = trim(enl%tiff_prefix) +hdferr = HDF_writeDatasetStringArray(dataset, line2, 1, HDF_head) +if (hdferr.ne.0) call HDF_handleError(hdferr,'HDFwriteEBSDNameList: unable to create tiff_prefix dataset',.TRUE.) + dataset = SC_anglefile line2(1) = trim(enl%anglefile) hdferr = HDF_writeDatasetStringArray(dataset, line2, 1, HDF_head) diff --git a/Source/EMsoftHDFLib/patternmod.f90 b/Source/EMsoftHDFLib/patternmod.f90 index 2129f467..48bb6b39 100644 --- a/Source/EMsoftHDFLib/patternmod.f90 +++ b/Source/EMsoftHDFLib/patternmod.f90 @@ -323,6 +323,8 @@ recursive function openExpPatternFile(filename, npat, L, inputtype, recsize, fun end if ! get the first byte to check if this file is version 1-3 or 4 ! version 4 has an extra byte in the header... + ! version 5 does as well, offsets the pattern offsets by an additional 25 bytes, + ! and increases the pattern headder from 16 to 42 bytes read(unit=funit, pos=1, iostat=ios) header ebspversion = 256-iachar(header) io_int(1) = ebspversion @@ -626,11 +628,12 @@ recursive subroutine getExpPatternRow(iii, wd, patsz, L, dims3, offset3, funit, case(5) ! "OxfordBinary" ! read position of patterns in file for a single row from the header - if (ebspversion.eq.4) then + if (ebspversion.gt.3) then read(unit=funit, pos=(liii-1)*lwd*8+10, iostat=ios) patoffsets else read(unit=funit, pos=(liii-1)*lwd*8+9, iostat=ios) patoffsets end if + if (ebspversion.eq.5) patoffsets = patoffsets + 25_8 ! generate a buffer to load individual patterns into buffersize = lL @@ -642,7 +645,11 @@ recursive subroutine getExpPatternRow(iii, wd, patsz, L, dims3, offset3, funit, do ii=1,lwd ! read each pattern into buffer with the 16 bytes of metadata skipped - read(unit=funit, pos=patoffsets(ii)+17_8, iostat=ios) buffer + if (ebspversion.eq.5) then + read(unit=funit, pos=patoffsets(ii)+43_8, iostat=ios) buffer + else + read(unit=funit, pos=patoffsets(ii)+17_8, iostat=ios) buffer + end if ! loop over pixels and convert the byte values into single byte integers do jj=1_ill,lL @@ -956,13 +963,18 @@ recursive subroutine getSingleExpPattern(iii, wd, patsz, L, dims3, offset3, funi else read(unit=funit, pos=(liii-1)*lwd*8+9, iostat=ios) patoffsets end if + if (ebspversion.eq.5) patoffsets = patoffsets + 25_8 ! generate buffers to load individual pattern into buffersize = lL allocate(buffer(buffersize), pairs(buffersize)) ! read single pattern into buffer with the 16 bytes of metadata skipped - read(unit=funit, pos=patoffsets(l1)+17_8, iostat=ios) buffer + if (ebspversion.eq.5) then + read(unit=funit, pos=patoffsets(l1)+43_8, iostat=ios) buffer + else + read(unit=funit, pos=patoffsets(l1)+17_8, iostat=ios) buffer + end if ! convert the byte values into single byte integers pairs = ichar(buffer) @@ -2622,7 +2634,7 @@ end subroutine PreProcessPatterns ! !> @date 11/30/18 MDG 1.0 original, based on EBSD routine !-------------------------------------------------------------------------- -recursive subroutine PreProcessTKDPatterns(nthreads, inRAM, tkdnl, binx, biny, masklin, correctsize, totnumexpt, & +recursive subroutine PreProcessTKDPatterns(nthreads, inRAM, tkdnl, binx, biny, mask, correctsize, totnumexpt, & epatterns, exptIQ) !DEC$ ATTRIBUTES DLLEXPORT :: PreProcessTKDPatterns @@ -2645,7 +2657,7 @@ recursive subroutine PreProcessTKDPatterns(nthreads, inRAM, tkdnl, binx, biny, m type(TKDIndexingNameListType),INTENT(IN) :: tkdnl integer(kind=irg),INTENT(IN) :: binx integer(kind=irg),INTENT(IN) :: biny -real(kind=sgl),INTENT(IN) :: masklin(binx*biny) +real(kind=sgl),INTENT(IN) :: mask(binx, biny) integer(kind=irg),INTENT(IN) :: correctsize integer(kind=irg),INTENT(IN) :: totnumexpt real(kind=sgl),INTENT(INOUT),OPTIONAL :: epatterns(correctsize, totnumexpt) @@ -2834,6 +2846,9 @@ recursive subroutine PreProcessTKDPatterns(nthreads, inRAM, tkdnl, binx, biny, m TKDPat(1:binx,kk) = exppatarray((jj-1)*patsz+(kk-1)*binx+1:(jj-1)*patsz+kk*binx) end do +! apply the mask + TKDpat = TKDpat * mask + if (present(exptIQ)) then ! compute the pattern Image Quality exptIQ((iii-iiistart)*jjend + jj) = sngl(computeEBSDIQ(binx, biny, TKDPat, ksqarray, Jres, planf)) @@ -2849,7 +2864,7 @@ recursive subroutine PreProcessTKDPatterns(nthreads, inRAM, tkdnl, binx, biny, m mi = minval(TKDPat) TKDpint = nint(((TKDPat - mi) / (ma-mi))*255.0) - TKDPat = float(adhisteq(tkdnl%nregions,binx,biny,TKDpint)) + TKDPat = float(adhisteq(tkdnl%nregions,binx,biny,TKDpint)) * mask ! convert back to 1D vector do kk=1,biny @@ -2857,7 +2872,7 @@ recursive subroutine PreProcessTKDPatterns(nthreads, inRAM, tkdnl, binx, biny, m end do ! apply circular mask and normalize for the dot product computation - exppatarray((jj-1)*patsz+1:(jj-1)*patsz+L) = exppatarray((jj-1)*patsz+1:(jj-1)*patsz+L) * masklin(1:L) + exppatarray((jj-1)*patsz+1:(jj-1)*patsz+L) = exppatarray((jj-1)*patsz+1:(jj-1)*patsz+L) ! * masklin(1:L) vlen = vecnorm(exppatarray((jj-1)*patsz+1:(jj-1)*patsz+L)) if (vlen.ne.0.0) then exppatarray((jj-1)*patsz+1:(jj-1)*patsz+L) = exppatarray((jj-1)*patsz+1:(jj-1)*patsz+L)/vlen diff --git a/Source/EMsoftLib/NameListHandlers.f90 b/Source/EMsoftLib/NameListHandlers.f90 index 0a535b2d..5d2ec580 100644 --- a/Source/EMsoftLib/NameListHandlers.f90 +++ b/Source/EMsoftLib/NameListHandlers.f90 @@ -4039,13 +4039,14 @@ recursive subroutine GetEBSDNameList(nmlfile, enl, initonly) character(fnlen) :: masterfile character(fnlen) :: energyfile ! removed from template file 05/16/19 [MDG] character(fnlen) :: datafile +character(fnlen) :: tiff_prefix ! define the IO namelist to facilitate passing variables to the program. namelist / EBSDdata / stdout, L, thetac, delta, numsx, numsy, xpc, ypc, anglefile, eulerconvention, masterfile, bitdepth, & energyfile, datafile, beamcurrent, dwelltime, energymin, energymax, binning, gammavalue, alphaBD, & scalingmode, axisangle, nthreads, outputformat, maskpattern, energyaverage, spatialaverage, & applyDeformation, Ftensor, includebackground, anglefiletype, makedictionary, hipassw, nregions, & - maskradius, poisson, Fframe + maskradius, poisson, Fframe, tiff_prefix ! set the input parameters to default values (except for xtalname, which must be present) stdout = 6 @@ -4088,6 +4089,7 @@ recursive subroutine GetEBSDNameList(nmlfile, enl, initonly) masterfile = 'undefined' ! filename energyfile = 'undefined' ! name of file that contains energy histograms for all scintillator pixels (output from MC program) datafile = 'undefined' ! output file name +tiff_prefix = 'undefined' ! used to output individual tiff files for patterns spatialaverage = 'n' if (present(initonly)) then @@ -4169,6 +4171,7 @@ recursive subroutine GetEBSDNameList(nmlfile, enl, initonly) ! user definition, if any, in the namelist file is overwritten here... enl%energyfile = enl%masterfile ! changed on 05/16/19 [MDG] enl%datafile = datafile +enl%tiff_prefix = tiff_prefix enl%spatialaverage = spatialaverage end subroutine GetEBSDNameList diff --git a/Source/EMsoftLib/NameListTypedefs.f90 b/Source/EMsoftLib/NameListTypedefs.f90 index a6b0cc0c..6cc2db46 100644 --- a/Source/EMsoftLib/NameListTypedefs.f90 +++ b/Source/EMsoftLib/NameListTypedefs.f90 @@ -630,6 +630,7 @@ module NameListTypedefs character(fnlen) :: targetfile character(fnlen) :: energyfile character(fnlen) :: datafile + character(fnlen) :: tiff_prefix end type EBSDNameListType ! namelist for the EMEBSDBatch program diff --git a/Source/SEM/EMEBSD.f90 b/Source/SEM/EMEBSD.f90 index e937abbe..102d7425 100644 --- a/Source/SEM/EMEBSD.f90 +++ b/Source/SEM/EMEBSD.f90 @@ -309,6 +309,8 @@ subroutine ComputeEBSDPatterns(enl, mcnl, mpnl, numangles, angles, EBSDMCdata, E use timing use stringconstants use math +use image +use, intrinsic :: iso_fortran_env IMPLICIT NONE @@ -381,8 +383,8 @@ subroutine ComputeEBSDPatterns(enl, mcnl, mpnl, numangles, angles, EBSDMCdata, E character(15) :: tstrb character(15) :: tstre character(10) :: char10 -character(fnlen) :: datafile -logical :: overwrite = .TRUE., insert = .TRUE., singlebatch +character(fnlen) :: datafile, TIFF_filename +logical :: overwrite = .TRUE., insert = .TRUE., singlebatch, tiff_output=.FALSE. character(5) :: bitmode integer(kind=irg) :: numbits real(kind=sgl) :: bitrange @@ -392,6 +394,15 @@ subroutine ComputeEBSDPatterns(enl, mcnl, mpnl, numangles, angles, EBSDMCdata, E Gmatrix(3,3), gs2c(3,3) logical :: includeFmatrix=.FALSE., noise +! declare variables for use in object oriented image module +integer :: iostat +character(len=128) :: iomsg +logical :: isInteger +type(image_t) :: im +character(6) :: TIFF_number +integer(int8) :: i8 (3,4) +integer(int8), allocatable :: TIFF_image(:,:) + !==================================== ! max number of OpenMP threads on this platform maxthreads = omp_get_max_threads() @@ -412,6 +423,8 @@ subroutine ComputeEBSDPatterns(enl, mcnl, mpnl, numangles, angles, EBSDMCdata, E call Message('Program will work in dictionary generation mode') end if +if (trim(enl%tiff_prefix).ne.'undefined') tiff_output = .TRUE. + ! define some energy-related parameters derived from MC input parameters !==================================== noise = .FALSE. @@ -1133,6 +1146,32 @@ subroutine ComputeEBSDPatterns(enl, mcnl, mpnl, numangles, angles, EBSDMCdata, E if (hdferr.ne.0) call HDF_handleError(hdferr,'HDF_writeHyperslabFloatArray3D EBSDpatterns') end if end if + +! ! should we write out individual patterns ? (tiff_output=.TRUE.) +! if ((trim(bitmode).eq.'char').and.(tiff_output.eqv..TRUE.)) then +! allocate(TIFF_image(binx,biny)) +! ! Create a tiff file name +! do i=1,dim2 +! TIFF_filename = trim(EMsoft_getEMdatapathname())//trim(enl%tiff_prefix) +! write (TIFF_number,"(I6.6)") iang-1 +! TIFF_filename = trim(TIFF_filename)//TIFF_number//'.tiff' +! TIFF_filename = EMsoft_toNativePath(TIFF_filename) +! ma = maxval(ECPpattern) +! mi = minval(ECPpattern) +! ECPpatternintd = ((ECPpattern - mi)/ (ma-mi)) +! if (enl%maskpattern.eq.'y') ECPpatternintd = ECPpatternintd * mask +! TIFF_image = nint(255.0*ECPpatternintd) +! ! set up the image_t structure +! im = image_t(TIFF_image) +! if(im%empty()) call Message("EMECP","failed to convert array to image") + +! ! create the file +! call im%write(trim(TIFF_filename), iostat, iomsg) ! format automatically detected from extension +! if(0.ne.iostat) then +! call Message("failed to write image to file : "//iomsg) +! end if +! end do +! end if !end if ! ===================================================== ! end of HDF_FileVersion = 4.0 write statements diff --git a/Source/SEM/EMEBSDmaster.f90 b/Source/SEM/EMEBSDmaster.f90 index c59dd49f..7f168bda 100644 --- a/Source/SEM/EMEBSDmaster.f90 +++ b/Source/SEM/EMEBSDmaster.f90 @@ -780,12 +780,12 @@ subroutine ComputeMasterPattern(emnl, progname, nmldeffile) karray(1:3,1) = sngl(ktmp%k(1:3)) karray(4,1) = sngl(ktmp%kn) kij(1:3,1) = (/ ktmp%i, ktmp%j, ktmp%hs /) - do ik=2,numk - ktmp => ktmp%next - karray(1:3,ik) = sngl(ktmp%k(1:3)) - karray(4,ik) = sngl(ktmp%kn) - kij(1:3,ik) = (/ ktmp%i, ktmp%j, ktmp%hs /) - end do + do ik=2,numk + ktmp => ktmp%next + karray(1:3,ik) = sngl(ktmp%k(1:3)) + karray(4,ik) = sngl(ktmp%kn) + kij(1:3,ik) = (/ ktmp%i, ktmp%j, ktmp%hs /) + end do ! and remove the linked list call Delete_kvectorlist(khead)