def cropGVE(grainfile, oldgvefile, newgvefile, verbose): grains = multigrainOutputParser.parse_GrainSpotter_log(grainfile) print "Parsed grains from %s" % grainfile print "Number of grains: %d" % len(grains) [peaksgve,idlist,header] = multigrainOutputParser.parseGVE(oldgvefile) print "Removing peaks which have been assigned to grains in %s" % grainfile for grain in grains: if (verbose): print "Looking at grain %s" % grain.getName() peaks = grain.getPeaks() # Sometimes, GrainSpotter indexes the same peak twice. We need to remove those double indexings peakid = [] for peak in peaks: peakid.append(peak.getPeakID()) peakid = list(set(peakid)) # remove duplicates, may loose the ordering but we do not care # Removing assign peaks from the list of g-vectors for thisid in peakid: try: index = idlist.index(thisid) except: print "Failed removing g-vector ID %d which was found in grain %s" % (thisid, grain.getName()) return if (verbose): print "Trying to remove peak %d from the list of g-vectors" % thisid del idlist[index] del peaksgve[index] multigrainOutputParser.saveGVE(peaksgve, header, newgvefile)
def setGVE(self, gvefile): [peaksgve, idlist, header] = multigrainOutputParser.parseGVE(gvefile) self.peakList = peaksgve self.npeaks = len(peaksgve) self.gvefile = gvefile self.twotheta = [] for peak in self.peakList: dsPeak = float(peak['ds']) self.twotheta.append( 2. * numpy.degrees(numpy.arcsin(dsPeak * self.wavelength / 2.)))
def RemoveUsedGVE(logfile, gve_input, gve_output): # Upload .log file from GrainSpotter : grains = multigrainOutputParser.parse_GrainSpotter_log(logfile) # Upload .gve file from ImageD11 : [peaksgve, idlist, header] = multigrainOutputParser.parseGVE(gve_input) # Display peak information : nb_start = len(peaksgve) gveToRemove = [] for grain in grains: peaks = grain.peaks for indexedPeak in peaks: #print 'Peak in grainFile' #print indexedPeak.getPeakID() #print indexedPeak.getTThetaMeasured() #print indexedPeak.getOmegaMeasured() #print indexedPeak.getEtaMeasured() #print 'Peak in gveFile' ID_grains = indexedPeak.getPeakID() ID_idlist = idlist.index(ID_grains) ID_gve = peaksgve[ID_idlist] #print ID_gve #print ID_gve['eta'] # Eliminate g-vectors which correspond to already indexed peaks : gveToRemove.append(ID_gve) #print nb_start #print len(peaksgve) #print len(gveToRemove) # Save the new list of (not indexed) peaks in .gve format : newPeakslist = [peaks for peaks in peaksgve if peaks not in gveToRemove] OutputPeaks = multigrainOutputParser.saveGVE(newPeakslist, header, gve_output) print '\n%s g-vectors were removed.' % len(gveToRemove) print '\nThe new list contains %s g-vectors.' % len(newPeakslist) print '\nSaved'
def gs_indexing_statistics(logfile, gve, gsinputfile, wavelength): """ Checks a grainspotter indexing performance Send the final GrainSpotter log, the list of g-vectors, the GS input file (with the loosest conditions), and the wavelength """ nphases = len(logfile) grains = [] ngrains = [] gsinput = [] nindexed = [] totalngrains = 0 totalindexedpeaks = 0 i = 0 # Parsing grain spotter output in input files # Extracting grain information for thislog in logfile: grains.append(multigrainOutputParser.parseGrains(thislog)) print("Parsed %s, found %d grains" % (thislog, len(grains[i]))) print("Parsing grain spotter input file %s." % (gsinputfile[i])) # Load the grain spotter input file gsinput.append(multigrainOutputParser.parseGSInput(gsinputfile[i])) print("\nGrainSpotter results for phase %d" % i) print("\t%d grains indexed" % (len(grains[i]))) nindexed.append(0) ngrains.append(len(grains[i])) totalngrains += len(grains[i]) for grain in grains[i]: nindexed[i] += grain.getNPeaks() print("\t%d g-vectors indexed" % (nindexed[i])) totalindexedpeaks += nindexed[i] tt = 1.0 * nindexed[i] / ngrains[i] print("\t%.1f g-vectors per grain in average" % (tt)) i = i + 1 print("") print("Done parsing grain files.\n") # Extract peak list and ds ranges in which to look for peak # For each phase, the list of peaks is on top of the gve file # Then, need keep a record of the ds tolerance for the peak (which could different for each phase) peakssample = [] peaksgve = [None] * nphases idlist = [None] * nphases for i in range(0, nphases): [peaksgve[i], idlist[i], header] = multigrainOutputParser.parseGVE(gve[i]) print( "Parsing header from GVE files %s to extract predicted sample peaks for phase %i" % (gve[i], i)) tttol = gsinput[i]["sigma_tth"] * gsinput[i]["nsigmas"] recordpeaks = False for line in header.split("\n"): if ((line.strip() == "# gx gy gz xc yc ds eta omega spot3d_id xl yl zl" )): recordpeaks = False # We reached the end of the header... if recordpeaks: try: tt = line.split() ds = float(tt[0]) h = int(tt[1]) k = int(tt[2]) l = int(tt[3]) tt = 2. * numpy.degrees(numpy.arcsin(wavelength * ds / 2.)) dsmin = 2. * numpy.sin(numpy.radians( (tt - tttol) / 2.)) / (wavelength) dsmax = 2. * numpy.sin(numpy.radians( (tt + tttol) / 2.)) / (wavelength) except ValueError: print( "Conversion error when reading predicted sample peaks from %s." % (gve[i])) print("Was trying to convert %s to ds, h, k, and l" % (line)) sys.exit(1) peakssample.append([ds, h, k, l, tt, dsmin, dsmax, tttol]) if ((line.strip() == "# ds h k l")): recordpeaks = True print( "\nRead theoretical peak positions in 2theta for all phases.\nI have a list of %d potential peaks for all %d phases.\n" % (len(peakssample), nphases)) # Merging peaks from GVE files, removing doubles allgves = peaksgve[0] allPeakIds = idlist[0] for i in range(1, nphases): missinggveID = set(idlist[i]).symmetric_difference(set(allPeakIds)) for peakid in missinggveID: ID_idlist = (idlist[i]).index(peakid) allPeakIds.append(peakid) allgves.append(peaksgve[i][ID_idlist]) print( "Merged unique g-vectors of all %d gve files. I now have %d experimental g-vectors." % (nphases, len(allgves))) # Loop on all experimental g-vectors # Are they in one of the 2 theta, omega, and eta ranges defined in grain spotter? # Need to check for all phases ds = [] eta = [] omega = [] keepPeak = [False] * len(allgves) for i in range(1, nphases): # Loop on phase gsinput[i]["dsranges"] = [] for tthrange in gsinput[i][ "tthranges"]: # Convert 2theta range to ds range for easier comparison ds0 = 2. * numpy.sin(numpy.radians( tthrange[0] / 2.)) / (wavelength) ds1 = 2. * numpy.sin(numpy.radians( tthrange[1] / 2.)) / (wavelength) (gsinput[i]["dsranges"]).append([ds0, ds1]) # Loop on peaks. If the peak is within the range, we keep it for later for j in range(0, len(allgves)): peak = allgves[j] thisds = float(peak['ds']) thiseta = normalizedAngle360(float( peak['eta'])) # In GrainSpotter, eta is in [0;360] thisomega = normalizedAngle180(float( peak['omega'])) # In GrainSpotter, omega is in [-180;180] test1 = 0 test2 = 0 test3 = 0 for dsrange in gsinput[i]["dsranges"]: if ((thisds >= dsrange[0]) and (thisds <= dsrange[1])): test1 = 1 for etarange in gsinput[i]["etaranges"]: if ((thiseta >= etarange[0]) and (thiseta <= etarange[1])): test2 = 1 #else: # print "Not for eta %.1f < %.1f < %.1f" % (etarange[0],thiseta,etarange[1]) for omegarange in gsinput[i]["omegaranges"]: if ((thisomega >= omegarange[0]) and (thisomega <= omegarange[1])): test3 = 1 #else: # print "Not for omega %.1f < %.1f < %.1f" % (omegarange[0],thisomega,omegarange[1]) if ( test1 * test2 * test3 == 1 ): # The peak is within the range of ttheta, eta, and omega for phase i. It could have been indexed. keepPeak[j] = True for j in range(0, len(allgves)): if (keepPeak[j]): peak = allgves[j] ds.append(float(peak['ds'])) eta.append(float(peak['eta'])) omega.append(float(peak['omega'])) print( "%d g-vectors within eta, omega, and 2theta ranges and could have been indexed." % (len(ds))) # Counting peak, within 2 theta range, and that can be assigned to the sample nassigned = 0 for thisds in ds: append = 0 for i in range(0, len(peakssample)): if ((thisds <= peakssample[i][6]) and (thisds >= peakssample[i][5])): append = 1 nassigned += append print( "%d g-vectors assigned to one of the sample peaks within these ranges." % (nassigned)) print("\nGlobal indexing performance") print( "\tOut of %d possible g-vectors, %d have been assigned to %d grains" % (nassigned, totalindexedpeaks, totalngrains)) tt = nassigned - totalindexedpeaks print("\t%d remaining g-vectors" % (tt)) tt = 100. * totalindexedpeaks / nassigned print("\t%.1f percents of g-vectors indexed" % (tt)) print() return
def test_grains(grainfile,gvefile,wavelength): """ Check a GrainSpotter log file against a GVE file This can be used to make sure that this exact GVE file was actually used to index the grains """ grains = multigrainOutputParser.parseGrains(grainfile) print ("Parsed %s, found %d grains" % (grainfile, len(grains))) # Load .gve file from ImageD11 : [peaksgve,idlist,header] = multigrainOutputParser.parseGVE(gvefile) # Try to see if all peaks in the indexed grains are in the gve print ("Making sure all indexed peak ID's are in the GVE file...") npeakstotal = 0 npeakserror = 0 for grain in grains : peaks = grain.peaks for indexedPeak in peaks : npeakstotal += 1 try: ID_grains = indexedPeak.getPeakID() ID_idlist = idlist.index(ID_grains) ID_gve = peaksgve[ID_idlist] except ValueError: print ("Peak %d of grain %s not found" % (ID_grains, grain.getName() )) npeakserror += 1 if (npeakserror > 10): print ("Too many errors, I stop here") return print ("I was looking for %d peaks from %d grains and got %d errors" % (npeakstotal, len(grains), npeakserror)) if (npeakserror > 0): print ("%s and %s do not seem to match" % (grainfile, gvefile)) return print ("All peaks in the grain file are in the GVE file. Now, looking for 2theta, eta, omega to see if they match...") for grain in grains : peaks = grain.peaks for indexedPeak in peaks : npeakstotal += 1 ID_grains = indexedPeak.getPeakID() omegaG = normalizedAngle(indexedPeak.getOmegaMeasured()) etaG = normalizedAngle(indexedPeak.getEtaMeasured()) tthetaG = indexedPeak.getTThetaMeasured() dsG = 2.*numpy.sin(numpy.radians(tthetaG/2.))/(wavelength) ID_idlist = idlist.index(ID_grains) #print peaksgve[ID_idlist] #return dsPeak = float(peaksgve[ID_idlist]['ds']) etaPeak = normalizedAngle(float(peaksgve[ID_idlist]['eta'])) omegaPeak = normalizedAngle(float(peaksgve[ID_idlist]['omega'])) if ((abs(etaG-etaPeak) > 0.01) or (abs(omegaPeak-omegaG) > 0.01) or (abs(dsG-dsPeak) > 0.001)): print ("Problem with peak %d of grain %s not found" % (ID_grains, grain.getName() )) print ("Expected: eta = %.2f , omega = %.2f, ds = %.4f" % (etaG, omegaG, dsG)) print ("Found: eta = %.2f , omega = %.2f, ds = %.4f" % (etaPeak, omegaPeak, dsPeak)) print ("Differences: eta = %.4f , omega = %.4f, ds = %.6f" % (abs(etaPeak-etaG), abs(omegaPeak-omegaG), abs(dsG-dsPeak))) npeakserror += 1 if (npeakserror > 10): print ("Too many errors, I stop here") return if (npeakserror > 0): print ("%s and %s do not seem to match" % (grainfile, gvefile)) return print ("All peaks in the grain file are in the GVE file and angles fully match.") return
def gs_indexing_statistics(logfile, gve, gsinput, wavelength): """ Checks a grainspotter indexing performance Send the final GrainSpotter log, the list of g-vectors, the GS input file (with the loosest conditions), and the wavelength """ grains = multigrainOutputParser.parseGrains(logfile) print "Parsed %s, found %d grains" % (logfile, len(grains)) # Load .gve file from ImageD11 : [peaksgve,idlist,header] = multigrainOutputParser.parseGVE(gve) # Extracting list of g-vectors from the header peakssample = [] recordpeaks = False #print header for line in header.split("\n"): if ((line.strip() == "# gx gy gz xc yc ds eta omega spot3d_id xl yl zl")): recordpeaks = False if recordpeaks: tt = line.split() ds = float(tt[0]) h = int(tt[1]) k = int(tt[2]) l = int(tt[3]) peakssample.append([ds,h,k,l]) #print h, k, l if ((line.strip() == "# ds h k l")): recordpeaks = True # Load the grain spotter input file gsinput = multigrainOutputParser.parseGSInput(gsinput) # Try to see if all g-vectors in the indexed grains are in the gve nindexed = 0 ngrains = len(grains) for grain in grains : nindexed += grain.getNPeaks() print "\nGrainSpotter results" print "\t%d grains indexed" % (len(grains)) print "\t%d g-vectors indexed" % (nindexed) tt = 1.0*nindexed/ngrains print "\t%.1f g-vectors per grain in average" % (tt) # Matching conditions in angle ranges ds = [] eta = [] omega = [] gsinput["dsranges"] = [] for tthrange in gsinput["tthranges"]: ds0 = 2.*numpy.sin(numpy.radians(tthrange[0]/2.))/(wavelength) ds1 = 2.*numpy.sin(numpy.radians(tthrange[1]/2.))/(wavelength) gsinput["dsranges"].append([ds0,ds1]) #print gsinput for peak in peaksgve: thisds = float(peak['ds']) thiseta = normalizedAngle360(float(peak['eta'])) # In GrainSpotter, eta is in [0;360] thisomega = normalizedAngle180(float(peak['omega'])) # In GrainSpotter, omega is in [-180;180] test1 = 0 test2 = 0 test3 = 0 for dsrange in gsinput["dsranges"]: if ((thisds >= dsrange[0]) and (thisds <= dsrange[1])): test1 = 1 for etarange in gsinput["etaranges"]: if ((thiseta >= etarange[0]) and (thiseta <= etarange[1])): test2 = 1 #else: # print "Not for eta %.1f < %.1f < %.1f" % (etarange[0],thiseta,etarange[1]) for omegarange in gsinput["omegaranges"]: if ((thisomega >= omegarange[0]) and (thisomega <= omegarange[1])): test3 = 1 #else: # print "Not for omega %.1f < %.1f < %.1f" % (omegarange[0],thisomega,omegarange[1]) if (test1*test2*test3 == 1): ds.append(float(peak['ds'])) eta.append(float(peak['eta'])) omega.append(float(peak['omega'])) print "\nPeaks" print "\t%d g-vectors in GVE file" % (len(peaksgve)) print "\t%d g-vectors within eta, omega, and 2theta ranges" % (len(ds)) # Counting peak, within 2 theta range, and that can be assigned to the sample tttol = gsinput["sigma_tth"]*gsinput["nsigmas"] dsmin = [] dsmax = [] #print tttol for samplepeak in peakssample: thisds = samplepeak[0] #print thisds tt = 2.*numpy.degrees(numpy.arcsin(wavelength*thisds/2.)) #print 2.*numpy.sin(numpy.radians((tt-tttol)/2.))/(wavelength) #print 2.*numpy.sin(numpy.radians((tt+tttol)/2.))/(wavelength) dsmin.append(2.*numpy.sin(numpy.radians((tt-tttol)/2.))/(wavelength)) dsmax.append(2.*numpy.sin(numpy.radians((tt+tttol)/2.))/(wavelength)) nassigned = 0 for thisds in ds: append = 0 for i in range(0,len(dsmin)): if ((thisds <= dsmax[i]) and (thisds >= dsmin[i])): append = 1 nassigned += append print "\t%d g-vectors assigned to sample within these ranges" % (nassigned) print "\nIndexing performance" print "\tOut of %d possible g-vectors, %d have been assigned to %d grains" % (nassigned, nindexed, len(grains)) tt = nassigned-nindexed print "\t%d remaining g-vectors" % (tt) tt = 100.*nindexed/nassigned print "\t%.1f percents of g-vectors indexed" % (tt) print return