picadae calibration programs
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

elbow.py 2.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. ##| Copyright: (C) 2019-2020 Kevin Larke <contact AT larke DOT org>
  2. ##| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file.
  3. import sys,os
  4. import numpy as np
  5. import common
  6. import rms_analysis
  7. def fit_points_to_reference( usL, dbL, usRefL, dbRefL ):
  8. dbV = None
  9. yyL = [ (db,dbRefL[ usRefL.index(us)]) for i,(us,db) in enumerate(zip(usL,dbL)) if us in usRefL ]
  10. if len(yyL) < 10:
  11. print("NO FIT")
  12. else:
  13. y0L,yrL = zip(*yyL)
  14. yN = len(y0L)
  15. A = np.vstack([np.ones(yN),y0L]).T
  16. c,m = np.linalg.lstsq(A,yrL,rcond=None)[0]
  17. dbV = (np.array(dbL) * m) + c
  18. return dbV
  19. def find_elbow( usL, dbL, pointsPerLine=5 ):
  20. ppl_2 = int(pointsPerLine/2)
  21. dL = []
  22. i = pointsPerLine
  23. # for each consecutive set of 'pointsPerLine' points in usL and dbL
  24. while i < len(usL):
  25. # find the x,y coordinates of the first 'ppl_2' coordinates
  26. x0L = np.array([ (us,1.0) for us in usL[i-pointsPerLine:i-ppl_2] ])
  27. y0L = np.array(usL[i-pointsPerLine:i-ppl_2])
  28. # find the x,y coordinates of the second 'ppl_2' coordinates
  29. x1L = np.array([ (us,1.0) for us in usL[i-ppl_2:i]])
  30. y1L = np.array(dbL[i-ppl_2:i])
  31. m0,c0 = np.linalg.lstsq(x0L,y0L,rcond=None)[0] # fit a line through the first set of points
  32. m1,c1 = np.linalg.lstsq(x1L,y1L,rcond=None)[0] # fit a line through the second set of points
  33. # store the angle between the two lines
  34. dL.append(m1-m0)
  35. i += 1
  36. # find the max angle
  37. i = np.argmax( dL )
  38. # return the x,y coordinate of the first data point of the second line
  39. return (usL[i+ppl_2],dbL[i+ppl_2])
  40. def find_elbow_main( cfg, inDir, midi_pitch, takeId ):
  41. inDir = os.path.join(inDir,str(pitch),str(takeId))
  42. analysisArgsD = cfg.analysisArgs['rmsAnalysArgs']
  43. r = rms_analysis_main( inDir, int(midi_pitch), **analysisD )
  44. usL = r.pkUsL
  45. dbL = r.pkDbL
  46. return find_elbow(r.pkUsL,r.pkDbL)
  47. if __name__ == "__main__":
  48. inDir = sys.argv[1]
  49. cfgFn = sys.argv[2]
  50. pitch = sys.argv[3]
  51. cfg = common.parse_yaml_cfg(cfgFn)
  52. find_elbow( cfg, inDir, pitch, 0 )