diff --git a/core/src/main/scala/se/lu/nateko/cp/meta/core/data/DataObject.scala b/core/src/main/scala/se/lu/nateko/cp/meta/core/data/DataObject.scala index 47e77a683..1142977c2 100644 --- a/core/src/main/scala/se/lu/nateko/cp/meta/core/data/DataObject.scala +++ b/core/src/main/scala/se/lu/nateko/cp/meta/core/data/DataObject.scala @@ -86,7 +86,7 @@ case class StationTimeSeriesMeta( productionInfo: Option[DataProduction], nRows: Option[Int], coverage: Option[GeoFeature], - columns: Option[Seq[VarMeta]] + columns: Seq[VarMeta] ) case class ValueType(self: UriResource, quantityKind: Option[UriResource], unit: Option[String]) @@ -108,7 +108,7 @@ case class SpatioTemporalMeta( station: Option[Station], samplingHeight: Option[Float], productionInfo: DataProduction, - variables: Option[Seq[VarMeta]] + variables: Seq[VarMeta] ){ def acquisition: Option[DataAcquisition] = station.map{ DataAcquisition(_, None, Some(temporal.interval), None, None, samplingHeight) @@ -164,11 +164,12 @@ case class DataObject( l2 => l2.coverage.orElse(l2.acquisition.coverage) ) + val cols = specificInfo.fold( + l3 => l3.variables, + l2 => l2.columns + ) + val varsAndPosits = for - cols <- specificInfo.fold( - l3 => l3.variables, - l2 => l2.columns - ).toSeq col <- cols deps <- col.instrumentDeployments.toSeq dep <- deps diff --git a/src/main/scala/se/lu/nateko/cp/meta/UploadDtos.scala b/src/main/scala/se/lu/nateko/cp/meta/UploadDtos.scala index d42b5b1b8..be4ece372 100644 --- a/src/main/scala/se/lu/nateko/cp/meta/UploadDtos.scala +++ b/src/main/scala/se/lu/nateko/cp/meta/UploadDtos.scala @@ -86,7 +86,7 @@ case class SpatioTemporalDto( forStation: Option[URI], samplingHeight: Option[Float], customLandingPage: Option[URI], - variables: Option[Seq[String]] + variables: Seq[String] ) case class DataProductionDto( diff --git a/src/main/scala/se/lu/nateko/cp/meta/services/UploadDtoReader.scala b/src/main/scala/se/lu/nateko/cp/meta/services/UploadDtoReader.scala index d37ebc102..6e2e96a71 100644 --- a/src/main/scala/se/lu/nateko/cp/meta/services/UploadDtoReader.scala +++ b/src/main/scala/se/lu/nateko/cp/meta/services/UploadDtoReader.scala @@ -47,7 +47,7 @@ object UploadDtoReader{ samplingHeight = l3.samplingHeight, production = dataProductionToDto(l3.productionInfo), customLandingPage = dobj.accessUrl.filterNot(uri => uri.getPath.endsWith(dobj.hash.id)), - variables = l3.variables.map(_.map(_.model.uri.toString.split('/').last)) + variables = l3.variables.map(_.model.uri.toString.split('/').last) )) case Right(l2) => Right(StationTimeSeriesDto( station = l2.acquisition.station.org.self.uri, diff --git a/src/main/scala/se/lu/nateko/cp/meta/services/citation/AttributionProvider.scala b/src/main/scala/se/lu/nateko/cp/meta/services/citation/AttributionProvider.scala index cdca67efb..a1dcb2329 100644 --- a/src/main/scala/se/lu/nateko/cp/meta/services/citation/AttributionProvider.scala +++ b/src/main/scala/se/lu/nateko/cp/meta/services/citation/AttributionProvider.scala @@ -65,10 +65,9 @@ final class AttributionProvider(vocab: CpVocab, val metaVocab: CpmetaVocab) exte if(dobj.specification.theme.self.uri === vocab.atmoTheme) memb => (memb.role.weight.isDefined && { val speciesOk = for( extra <- memb.role.extra; - l2 <- dobj.specificInfo.toOption; - cols <- l2.columns + l2 <- dobj.specificInfo.toOption ) yield{ - val colLabels = cols.map(_.label.toLowerCase) + val colLabels = l2.columns.map(_.label.toLowerCase) extra.split(',').map(_.trim.toLowerCase).exists(species => colLabels.exists(_.contains(species)) || dobj.specification.self.label.getOrElse("").toLowerCase.contains(species) diff --git a/src/main/scala/se/lu/nateko/cp/meta/services/citation/CitationMaker.scala b/src/main/scala/se/lu/nateko/cp/meta/services/citation/CitationMaker.scala index dc3f5e42d..d9f5205ac 100644 --- a/src/main/scala/se/lu/nateko/cp/meta/services/citation/CitationMaker.scala +++ b/src/main/scala/se/lu/nateko/cp/meta/services/citation/CitationMaker.scala @@ -177,9 +177,11 @@ class CitationMaker( val height = acq.samplingHeight.fold("")(sh => s" ($sh m)") val vars = if dobj.specification.self.uri === vocab.atmGhgProdSpec then - stationTs.columns.fold("")(_.collect{ - case v if v.valueType.unit.isDefined => v.label - }.mkString(" (", ", ", ")")) + if (stationTs.columns.nonEmpty) + stationTs.columns.collect{ + case v if v.valueType.unit.isDefined => v.label + }.mkString(" (", ", ", ")") + else "" else "" s"$spec$vars from $station$height" diff --git a/src/main/scala/se/lu/nateko/cp/meta/services/metaexport/SchemaOrg.scala b/src/main/scala/se/lu/nateko/cp/meta/services/metaexport/SchemaOrg.scala index 6f6811576..c7850dcb0 100644 --- a/src/main/scala/se/lu/nateko/cp/meta/services/metaexport/SchemaOrg.scala +++ b/src/main/scala/se/lu/nateko/cp/meta/services/metaexport/SchemaOrg.scala @@ -183,7 +183,7 @@ class SchemaOrg(handleProxies: HandleProxiesConfig)(using envri: Envri, envriCon ) } - val variableMeasured = asOptArray(dobj.specificInfo.fold(_.variables, _.columns))( + val variableMeasured = asOptArray(dobj.specificInfo.fold((_.variables), _.columns))( variable => JsObject( "@type" -> JsString("PropertyValue"), "name" -> JsString(variable.label), diff --git a/src/main/scala/se/lu/nateko/cp/meta/services/upload/DobjMetaReader.scala b/src/main/scala/se/lu/nateko/cp/meta/services/upload/DobjMetaReader.scala index 0ef04e06e..d8b9b4bda 100644 --- a/src/main/scala/se/lu/nateko/cp/meta/services/upload/DobjMetaReader.scala +++ b/src/main/scala/se/lu/nateko/cp/meta/services/upload/DobjMetaReader.scala @@ -272,7 +272,7 @@ trait DobjMetaReader(val vocab: CpVocab) extends CpmetaReader: case Some(interval) => addInstrDeplInfo(stationUri, interval, columns) columnsOptV.sinkOption.map: columnsOpt => - StationTimeSeriesMeta(acq, prod, nRows, lblCoverage, columnsOpt) + StationTimeSeriesMeta(acq, prod, nRows, lblCoverage, columnsOpt.getOrElse(Nil)) resV.flatMap(identity) end getStationTimeSerMeta @@ -325,7 +325,7 @@ trait DobjMetaReader(val vocab: CpVocab) extends CpmetaReader: station = station, samplingHeight = samplingHeightOpt.flatten, productionInfo = prod, - variables = Some(variables.flatten).filterNot(_.isEmpty) + variables = variables.flatten() ) def getContributors(objIri: IRI, contribPredicate: IRI)(using conn: DobjConn | DocConn): Validated[IndexedSeq[Agent]] = diff --git a/src/main/scala/se/lu/nateko/cp/meta/services/upload/StatementsProducer.scala b/src/main/scala/se/lu/nateko/cp/meta/services/upload/StatementsProducer.scala index ecec21ca0..f00a40f89 100644 --- a/src/main/scala/se/lu/nateko/cp/meta/services/upload/StatementsProducer.scala +++ b/src/main/scala/se/lu/nateko/cp/meta/services/upload/StatementsProducer.scala @@ -201,7 +201,7 @@ class StatementsProducer(vocab: CpVocab, metaVocab: CpmetaVocab) { makeSt(acq, metaVocab.prov.wasAssociatedWith, meta.forStation.map(_.toRdf)) ++ makeSt(acq, metaVocab.hasSamplingHeight, meta.samplingHeight.map(vocab.lit)) ++ makeSt(objUri, RDFS.SEEALSO, meta.customLandingPage.map(_.toRdf)) ++ - meta.variables.toSeq.flatten.flatMap(getL3VarInfoStatements(objUri, hash, _)) + meta.variables.flatMap(getL3VarInfoStatements(objUri, hash, _)) } private def getStationDataStatements(hash: Sha256Sum, meta: StationTimeSeriesDto)(using Envri): Seq[Statement] = { diff --git a/src/main/scala/se/lu/nateko/cp/meta/services/upload/validation/UploadValidator.scala b/src/main/scala/se/lu/nateko/cp/meta/services/upload/validation/UploadValidator.scala index b6594bb58..060273216 100644 --- a/src/main/scala/se/lu/nateko/cp/meta/services/upload/validation/UploadValidator.scala +++ b/src/main/scala/se/lu/nateko/cp/meta/services/upload/validation/UploadValidator.scala @@ -338,14 +338,16 @@ class UploadValidator(servers: DataObjectInstanceServers): if spec.specificDatasetType != DatasetType.SpatioTemporal then errors += "Wrong type of dataset for this object spec (must be spatiotemporal)" else - for vars <- spTempMeta.variables do spec.datasetSpec.fold( - errors += s"Data object specification ${spec.self.uri} lacks a dataset specification; cannot accept variable info." - ): dsSpec => - val valTypeLookupV = metaReader.getValTypeLookup(dsSpec.self.uri.toRdf) - errors ++= valTypeLookupV.errors - for valTypeLookup <- valTypeLookupV; varName <- vars do - if valTypeLookup.lookup(varName).isEmpty then errors += - s"Variable name '$varName' is not compatible with dataset specification ${dsSpec.self.uri}" + if (spTempMeta.variables.nonEmpty) { + spec.datasetSpec.fold( + errors += s"Data object specification ${spec.self.uri} lacks a dataset specification; cannot accept variable info." + ): dsSpec => + val valTypeLookupV = metaReader.getValTypeLookup(dsSpec.self.uri.toRdf) + errors ++= valTypeLookupV.errors + for valTypeLookup <- valTypeLookupV; varName <- spTempMeta.variables do + if valTypeLookup.lookup(varName).isEmpty then errors += + s"Variable name '$varName' is not compatible with dataset specification ${dsSpec.self.uri}" + } case Right(stationMeta) => if spec.specificDatasetType != DatasetType.StationTimeSeries diff --git a/src/main/twirl/views/DataLandingPage.scala.html b/src/main/twirl/views/DataLandingPage.scala.html index 1934cb3c4..d0a42f5c9 100644 --- a/src/main/twirl/views/DataLandingPage.scala.html +++ b/src/main/twirl/views/DataLandingPage.scala.html @@ -133,7 +133,7 @@
| @(varInfo.label) | @(varInfo.valueType.self.label.getOrElse("")) | @@ -402,7 +402,7 @@