Skip to main content

NASA's Nancy Grace Roman Space Telescope Arrives In Florida

2 weeks 1 day ago
NASA's Nancy Grace Roman Space Telescope has arrived at Kennedy Space Center ahead of a Falcon Heavy launch targeted for no earlier than August 30. The observatory will survey the sky about 1,000 times faster than Hubble with a field of view at least 100 times wider, helping scientists study dark matter, dark energy, and exoplanets. Spaceflight Now reports: NASA's next great observatory, the Nancy Grace Roman Space Telescope, arrived at the Kennedy Space Center aboard the agency's massive Pegasus barge late Sunday morning. The spacecraft was nestled inside its protective case, which NASA nicknamed the "Chariot" in keeping with the "Roman" theme. That said, telescope is named not for the ancient empire, but instead for NASA's first Chief of Astronomy, Nancy Grace Roman. "She was a key person in our exploration of space. She understood that in order to better understand the universe, you have to go in space," said Lucas Paganini, the program executive for Roman. "That's why she's called the 'Mother of Hubble' because she made Hubble possible." [...] Roman is designed to operate near a fixed point in space called Lagrange Point 2, about 1.5 million km away from the Earth on the side opposite the Sun. It's designed to operate there for a minimum of five years, but Paganini said with the propellant onboard, it will likely last for 10 years or more. The telescope is+ equipped with a 300 megapixel camera called the Wide Field Instrument, which features 18 detectors. It was developed by BAE Systems (formerly Ball Aerospace). "It's going to allow us to observe at least 100 times wider field of view than what we can do with Hubble. Same resolution, but a wider area, 1000 times faster," Paganini said. "So what takes Roman a year to observe, it would take Hubble thousands of years. So it's definitely much more efficient." The observatory also features a chronograph instrument, developed by the Jet Propulsion Laboratory, which will allow Roman to observe the faint light of exoplanets near their stars. Paganini said Roman will also help scientists better understand dark matter and dark energy, the combination of which he calls the "dark universe." "100 years ago, we discovered that the universe was expanding. 25 years ago, we discovered that it was expanding at an accelerated pace and that's what led to a Nobel Prize," Paganini said. "What we don't quite know yet is if that acceleration is changing in ways. We don't know if it's actually dark energy, what is producing it, or is it simply that we don't understand gravity at all. "So eventually, we'll see if the laws of physics that we use these days are the right ones for what we are observing. But at the end is, we're trying to understand a very human question, which is where do we come from and where are wea heading in this universe that is our neighborhood?"

Read more of this story at Slashdot.

BeauHD

CodeSOD: Do a Lot to Do Nothing

2 weeks 1 day ago

Today's anonymous submitter works in finance. I'll let them start the introduction:

This is a legacy application that has been running for nearly a decade in production so one could say that it's been thoroughly tested by daily production use and nothing needs changing

This is a collection of two C# methods, and we'll start with ValueAGPFund, which isn't a WTF per se, but definitely not code I'd want to maintain either.

public Valuation ValueAGPFund(int valuationId, ValueAFundParameters parameters, CapitalAccount capitalAccount, int? lotId) { if (parameters.UseActiveCoefficientSet) { parameters.CoefficientSet = _coefficientSetQueries.GetActive(); } parameters.InternationalDveCoefficientSets = _coefficientSetQueries.GetInternationalDveActive(); var referenceData = _referenceDataFactory.CreateReferenceData(parameters, capitalAccount); if (lotId != null) { var di = referenceData.FundDirectInvestments.Where(x => x.PositionId == lotId); referenceData.FundDirectInvestments = di; } var countryMappings = _countryQueries.GetFullIsoCountryList(); var valuation = _valuationFactory.Initialise(referenceData, parameters, countryMappings); valuation = ApplyValuators(valuation, referenceData, _valuatorFactory.CreateValuators(valuation, this)); var valuationForCoverage = _valuationQueries.GetWithDirectValuationsAndFundValuations(valuationId); valuation = ApplyCoverage(valuation, valuationForCoverage); foreach (var fv in valuation.FundValuations) { _logger.Info($"Debugging distributions: for fund (parameter fund id = {parameters.FundId}, valuation fund id = {valuation.FundId}, fund valuation fund id = {fv.GpFundId}) in valuation {valuationId}," + $" loaded fund investment distributions from {string.Join(", ", fv.FundInvestmentDistributions.Select(x => $"{x.InvestmentId}:{x.TransactionDate:yyyy/MM/dd}"))}"); } foreach (var fv in valuation.FundValuations.Where(x => parameters.InvestmentIds.Contains(x.EqtInvestmentId))) { fv.ValuationId = valuationId; _fundValuationCommands.Add(fv); } foreach (var dv in valuation.DirectValuations.Where(x => x.LotIdDiOnly == lotId)) { dv.ValuationId = valuationId; _directValuationCommands.Add(dv); } foreach (var vw in valuation.ValuationWarnings) { vw.ValuationId = valuationId; _valuationWarningCommands.Add(vw); } var previousValuation = CheckPreviousValuationIfRequired(valuationId, parameters, capitalAccount, lotId); if (previousValuation != null) valuation.ChildValuations.Add(previousValuation); if (parameters.Frequency == ValuationFrequency.Daily) { var unapprovedValuations = _valuationQueries.GetList(valuation.FundId, valuation.ValuationDate, valuation.Frequency, valuation.Purpose) .Where(x => x.IsApproved == ValuationStatus.Unapproved) .ToList(); _valuationCommands.Delete(unapprovedValuations.Select(x => x.Id).ToArray()); } valuation.Id = valuationId; _valuationCommands.Update(valuation); _valuationCacheService.Refresh(valuation.Frequency, true); return valuation; }

The key problem with this function is that it's got loads of side effects. It modifies the parameters parameter, which while it was passed by value, the value itself is a reference, so you are updating it on the caller, whether the caller likes it or not. It also modifies a bunch of internal class members. It's also just… doing a lot of different steps. It's not a WTF, but it's bad code. Note the call in the middle to CheckPreviousValuationIfRequired- we're going to come back to that in a second.

Let's take a look at how it's called.

private Valuation CheckPreviousValuationIfRequired(int valuationId, ValueAFundParameters parameters, CapitalAccount capitalAccount, int? lotId) { if ((parameters.Frequency == ValuationFrequency.Quarterly || parameters.Frequency == ValuationFrequency.Monthly) && ValuationPurposeHelper.UserGenerated(parameters.Frequency).Contains(parameters.Purpose)) { var inPeriodParams = new ValueAFundParameters { FundId = parameters.FundId, ValuationDate = parameters.ValuationDate.GetPreviousValuationDate(parameters.Frequency), CreatedBy = parameters.CreatedBy, Purpose = ValuationPurpose.InPeriodCalculation, Frequency = parameters.Frequency, InvestmentIds = parameters.InvestmentIds, UseActiveCoefficientSet = true, UseAmericanDve = parameters.UseAmericanDve, ValuationOptions = parameters.ValuationOptions }; var openingValuation = _valuationQueries.GetInPeriodOpeningValuation(inPeriodParams.FundId, inPeriodParams.ValuationDate, valuationId); //return openingValuation == null // ? null // : ValueAGPFund(openingValuation.Id, inPeriodParams, capitalAccount, lotId); return openingValuation == null ? ValueAGPFund(openingValuation.Id, inPeriodParams, capitalAccount, lotId) : null; } return null; }

This function checks the input parameters. Depending on the values, it will either return null, or it will call ValueAGPFund. Wait a second, ValueAGPFund calls this function. That's not good.

But let's really focus in on the return statement and its comment:

//return openingValuation == null // ? null // : ValueAGPFund(openingValuation.Id, inPeriodParams, capitalAccount, lotId); return openingValuation == null ? ValueAGPFund(openingValuation.Id, inPeriodParams, capitalAccount, lotId) : null;

The current version checks if openingValuation is null, and if it is, tries to access it, thus triggering a NullReferenceException. This function either returns null or throws a NullReferenceException. So all that worrying about side effects and circular calls doesn't matter, but this likely isn't correct. The comment indicates that there used to be a correct version, which only called ValueAGPFund if the valuation wasn't null- but that version likely had all the problems of circular calls and unpredictable side effects.

As it stands, the application as a whole works. Since CheckPreviousValuationIfRequired only ever returns null or throws an exception, and since ValueAGPFund is only called from here, it looks like these functions could just both be removed without problems. But our submitter is wary of doing that:

The problem is that I first need to figure out whether 1) this piece of code produces any side effects and 2) nobody is relying on the System.NullReferenceException being thrown here.

No worries, though, right? I'm sure your unit tests will catch any regressions caused by removing that. Because this is the kind of code that definitely has great unit tests.

.comment { border: none; } [Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.
Remy Porter