package femr.util.calculations; import femr.common.models.PatientItem; import femr.common.models.VitalItem; import femr.util.DataStructure.Mapping.VitalMultiMap; import java.math.BigDecimal; //Importing for converting import java.util.List; import java.util.Map; /** * Created by owner1 on 3/11/2015. */ public class LocaleUnitConverter { /** * Converts all imperial values in a VitalMultiMap to metric values * @param vitalMap MultiMap to get imperial values from and store metric values into * @return VitalMultiMap with metric values */ public static VitalMultiMap toMetric(VitalMultiMap vitalMap) { for (int dateIndex = 0; dateIndex < vitalMap.getDateListChronological().size(); dateIndex++) { // Get imperial temperature(F) String tempC = vitalMap.get("temperature", vitalMap.getDate(dateIndex)); // If temp is not null convert to metric(C) and store in map as temperatureCelsius if (tempC != null) { vitalMap.put("temperatureCelsius", vitalMap.getDate(dateIndex), getCelcius(tempC)); // temperature is in Fahrenheit } // Get imperial height from Map String feetS = vitalMap.get("heightFeet", vitalMap.getDate(dateIndex)); String inchesS = vitalMap.get("heightInches", vitalMap.getDate(dateIndex)); if (feetS != null && inchesS != null) { // Convert Height to Metric Integer meters = getMeters(feetS, inchesS); Integer cm = getCentimetres(feetS, inchesS); // Store metric height in multimap as heightMeters and heightCm vitalMap.put("heightMeters", vitalMap.getDate(dateIndex), meters); // puts it back into map vitalMap.put("heightCm", vitalMap.getDate(dateIndex), String.format("%02d", cm)); // puts it back into map } // Get the imperial weight String lbs = vitalMap.get("weight", vitalMap.getDate(dateIndex)); if (lbs != null) { // Convert to metric and store as weightKgs vitalMap.put("weightKgs", vitalMap.getDate(dateIndex), getKgs(lbs)); // puts it back into map } } return vitalMap; } /** * Converts all imperial values in a PatientItem to metric values * @param patient PatientItem to get imperial values from and store metric values into * @return PatientItem with metric values */ public static PatientItem toMetric(PatientItem patient) { if (patient == null) return patient; // Store seperate height variables temporarily // Wish getHeightFeet() and getHeightInches() were'nt stored as Integer in PatientItem. // Causes issues with precision when value stored in database as a non whole number if (patient.getHeightFeet() != null && patient.getHeightInches() != null) { Integer feet = patient.getHeightFeet(); Integer inches = patient.getHeightInches(); //added for femr-136 - dulal unit display patient.setHeightFeetDual(patient.getHeightFeet()); patient.setHeightInchesDual(patient.getHeightInches()); // Overwrite patient height feet with meters patient.setHeightFeet(LocaleUnitConverter.getMeters(feet, inches)); // Overwrite patient height inches with centimeters patient.setHeightInches(LocaleUnitConverter.getCentimetres(feet, inches)); } // Overwrite patients weight with kg if (patient.getWeight() != null) { patient.setWeight(LocaleUnitConverter.getKgs(patient.getWeight()).floatValue()); //added for femr-136 - dual unit display patient.setWeightDual(LocaleUnitConverter.getLbs(patient.getWeight())); } return patient; } /** * Added for femr-136 - dual unit display * Converts all imperial values in a PatientItem to metric values for dual unit display * @param patient PatientItem to get imperial values from and store metric values into * @return PatientItem with metric values */ public static PatientItem forDualUnitDisplay(PatientItem patient) { if (patient == null) return patient; // Store seperate height variables temporarilyl // Wish getHeightFeet() and getHeightInches() were'nt stored as Integer in PatientItem. // Causes issues with precision when value stored in database as a non whole number if (patient.getHeightFeet() != null && patient.getHeightInches() != null) { Integer feet = patient.getHeightFeet(); Integer inches = patient.getHeightInches(); // Overwrite patient height feet with meters patient.setHeightFeetDual(LocaleUnitConverter.getMeters(feet, inches)); // Overwrite patient height inches with centimeters patient.setHeightInchesDual(LocaleUnitConverter.getCentimetres(feet, inches)); } // Overwrite patients weight with kg if (patient.getWeight() != null) { patient.setWeightDual(LocaleUnitConverter.getKgs(patient.getWeight()).floatValue()); } return patient; } /** * Converts vitals to imperial (Map<String, Float> used when user is submitting vitals * @param vitalMap Map of all patient vitals * @return The Map with the vitals converted to imperial */ public static Map<String, Float> toImperial(Map<String, Float> vitalMap) { if (vitalMap.containsKey("temperature")) vitalMap.put("temperature", getFahrenheit(vitalMap.get("temperature"))); if (vitalMap.containsKey("heightFeet") && vitalMap.containsKey("heightInches")) { Float heightMetres = vitalMap.get("heightFeet"); Float heightCentimetres = vitalMap.get("heightInches"); // AS - Convert and store in original height variables vitalMap.put("heightFeet" ,getFeet(heightMetres, heightCentimetres)); vitalMap.put("heightInches", getInches(heightMetres, heightCentimetres)); } if (vitalMap.containsKey("weight")) vitalMap.put("weight", getLbs(vitalMap.get("weight"))); return vitalMap; } /** * Converts a Fahrenheit temperature to celcius * @param Fahrenheit The temperature to convert to celcius * @return The temperature in celcius (As BigDecimal for precision) */ public static BigDecimal getCelcius(Float Fahrenheit) { return roundFloat((Fahrenheit - 32) * 5 / 9, 2); // (°F - 32) x 5/9 = °C } /** * Overload for getCelcius(Float) that accepts Fahrenheit as a string * @param FahrenheitString the temperature as a string * @return The temperature in celcius (As BigDecimal for precision) */ public static BigDecimal getCelcius(String FahrenheitString) { Float Fahrenheit = Float.parseFloat(FahrenheitString); return getCelcius(Fahrenheit); } /** * Converts a Celcius temperature to Fahrenheit * @param Celcius Temperature to convert to Fahrenheit * @return The temperature in Fahrenheit */ public static float getFahrenheit(float Celcius) { return Celcius * 9/5 + 32; } /** * Converts a height from Feet & inches into meters portion of a height (2.43) * @param Feet Height in feet * @param Inches Height in inches * @return Height in meters (ie 2.43 returns 2)) */ public static Integer getMeters(Integer Feet, Integer Inches) { /* Calculate total inches (feet*12)+inches */ Float totalInches = (float)(Inches + Feet * 12); return (int)Math.floor(totalInches * 0.0254f); } /** * Overload method for getMeters(Integer, Integer). * Converts a height from Feet & inches into meters portion of a height (2.43) * @param Feet Height in feet * @param Inches Height in inches * @return Height in meters (ie 2.43 returns 2)) */ public static Integer getMeters(Float Feet, Float Inches) { return getMeters(Math.round(Feet), Math.round(Inches)); } /** * Overload method for getMeters(Integer, Integer). * Converts a height from Feet & inches into meters portion of a height (2.43) * @param Feet Height in feet * @param Inches Height in inches * @return Height in meters (ie 2.43 returns 2) */ public static Integer getMeters(String Feet, String Inches) { if (Feet == null || Inches == null) return 0; return getMeters(Math.round(Float.parseFloat(Feet)), Math.round(Float.parseFloat(Inches))); } /** * Converts a height from Feet & inches into centimeters portion of a height (1.55) * @param Feet Height in feet * @param Inches Height inches * @return The height in centimeters (ie 1.55 returns 55) */ public static Integer getCentimetres(Float Feet, Float Inches) { /* Calculate total inches (feet*12)+inches */ Float totalInches = Inches + Feet * 12; /* Convert inches to cm */ Integer cm = Math.round(totalInches * 2.54f); return cm % 100; } /** * Overload method for getCentimetres(Float, Float). * Converts a height from Feet & inches into centimeters portion of a height (1.55) * @param Feet Height in feet * @param Inches Height inches * @return The height in centimeters (ie 1.55 returns 55) */ public static Integer getCentimetres(Integer Feet, Integer Inches) { return getCentimetres((float)Feet, (float)Inches); } /** * Overload method for getCentimetres(Float, Float). * Converts a height from Feet & inches into centimeters portion of a height (1.55) * @param Feet Height in feet * @param Inches Height inches * @return The height in centimeters (ie 1.55 returns 55) */ public static Integer getCentimetres(String Feet, String Inches) { if (Feet == null || Inches == null) return 0; return getCentimetres(Float.parseFloat(Feet), Float.parseFloat(Inches)); } /** * Converts a height in Metres and centimetres to feet portion of a height (5'11") * @param Metres Height in metres * @param Centimetres Height in centimetres * @return Height in feet (ie 5'11" returns 5') */ public static Float getFeet(Float Metres, Float Centimetres) { Float totalCm = Metres * 100 + Centimetres; Float totalInches = totalCm * 0.39370f; return (float)Math.floor(totalInches / 12); } /** * Converts a height in Metres and centimetres to inches portion of a height (5'11") * @param Metres Height in metres * @param Centimetres Height in centimetres * @return Height in inches (ie 5'11" returns 11") */ public static Float getInches(Float Metres, Float Centimetres) { Float totalCm = Metres * 100 + Centimetres; Float totalInches = totalCm * 0.39370f; return totalInches % 12; } /** * Converts weight in pounds(lbs) to kilograms(KG) * @param lbs Weight in pounds * @return Weight in kilograms */ public static BigDecimal getKgs(Float lbs) { return roundFloat(lbs / 2.2046f, 2); } /** * Overload method for getKgs(Float) * Converts weight in pounds(lbs) to kilograms(kg) * @param lbs Weight in pounds * @return Weight in kilograms */ public static BigDecimal getKgs(String lbs) { if (lbs == null) return BigDecimal.ZERO; // return getKgs(Float.parseFloat(lbs)); return getKgs(Float.parseFloat(lbs)); } /** * Convert weight in Kilograms(kg) to pounds(lbs) * @param kgs Weight in kilograms * @return Weight in pounds */ public static Float getLbs(Float kgs) { return kgs * 2.2046f; } /** * Rounds a float to 2 decimal places. Needed to resolve issues with * floats given by existing code * @param number Number to round * @param decimalPlaces Number of decimal places to rund to * @return Rounded number as a BigDecimal */ private static BigDecimal roundFloat(Float number, int decimalPlaces) { BigDecimal bd = new BigDecimal(Float.toString(number)); bd = bd.setScale(decimalPlaces, BigDecimal.ROUND_HALF_UP); return bd; } }