⚠ This page is served via a proxy. Original site: https://github.com
This service does not collect credentials or authentication data.
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/firefly/js/data/FileAnalysis.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,13 @@ export const Format= {
FITS: 'FITS',
ASDF: 'ASDF',
JSON: 'JSON',
YAML: 'YAML',
TEXT: 'TEXT',
PDF: 'PDF',
TAR: 'TAR',
PNG: 'PNG',
GZIP: 'GZIP',
HTML: 'HTML',
REGION: 'REGION',
VO_TABLE: 'VO_TABLE',
VO_TABLE_TABLEDATA: 'VO_TABLE_TABLEDATA',
Expand Down
137 changes: 26 additions & 111 deletions src/firefly/js/metaConvert/AnalysisUtils.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
import {FileAnalysisType} from '../data/FileAnalysis.js';
import {getCellValue, getColumns, hasRowAccess} from '../tables/TableUtil.js';
import {getDataServiceOptionByTable} from '../ui/tap/DataServicesOptions';
import {tokenSub} from '../util/WebUtil';
import {FileAnalysisType, Format} from '../data/FileAnalysis.js';
import {hasRowAccess} from '../tables/TableUtil.js';
import {PlotAttribute} from '../visualize/PlotAttribute.js';
import {getObsCoreAccessFormat, getObsTitle} from '../voAnalyzer/TableAnalysis';
import {
isGzipType, isHtmlType, isJSONType, isPDFType, isPlainTextType, isSimpleImageType, isTarType, isYamlType
isGzipType, isHtmlType, isJSONType, isPDFType, isSimpleImageType, isTarType, isYamlType
} from '../voAnalyzer/VoDataLinkServDef';
import {dispatchActivateFileMenuItem, dispatchUpdateDataProducts} from './DataProductsCntlr.js';
import {
dispatchActivateFileMenuItem, dispatchActivateMenuItem, dispatchUpdateDataProducts
} from './DataProductsCntlr.js';
import {
dpdtDownload,
dpdtImage, dpdtMessage, dpdtMessageWithDownload, dpdtPNG, dpdtSimpleMsg, dpdtText, dpdtWorkingMessage,
dpdtWorkingPromise,
DPtypes
dpdtDownload, dpdtImage, dpdtMessage, dpdtMessageWithDownload, dpdtPNG, dpdtSimpleMsg, dpdtText, dpdtWorkingMessage,
dpdtWorkingPromise, DPtypes
} from './DataProductsType.js';
import {createGridImagesActivate} from './ImageDataProductsUtil.js';
import {doUploadAndAnalysis} from './UploadAndAnalysis.js';
import {getBasicTitling, makeObsTitleExtension} from './VoUITitles';

const LOADING_MSG= 'Loading...';

Expand Down Expand Up @@ -197,7 +192,6 @@ export function doFileNameAndTypeAnalysis({url, ct, wrapWithMessage=true, name,

if (isUsableDownloadType(ext,ct)) item= makeDownloadType(url,ext,ct,wrapWithMessage, name, obsTitle);
else if (imExt.some( (e) => ext.includes(e)) || isSimpleImageType(ct)) item= makePngEntry(url, name, obsTitle);
// else if (ext.endsWith('txt') || isPlainTextType(ct)) item= makeTextEntry(url, name, obsTitle);
else if (ext.endsWith('yaml') || isYamlType(ct)) item= makeYamlEntry(url, name, obsTitle);
else if (ext.endsWith('json') || isJSONType(ct)) item= makeJsonEntry(url, name, obsTitle);
if (item) item.contentType= ct;
Expand Down Expand Up @@ -240,67 +234,37 @@ export function makeDownloadType(url,ext,ct,wrapWithMessage,name, obsTitle) {
}
}

function makeOtMsg(obsTitle) {
if (!obsTitle) return '';
const otBase= obsTitle.length>25 ? obsTitle.substring(0,29) : obsTitle;
return ` (${otBase})`;
}


export function makePdfEntry(url,name, obsTitle) {
const otMsg= makeOtMsg(obsTitle);
return dpdtDownload('Download PDF File'+otMsg, url, 'download-0', 'pdf',
{
message: 'This is a PDF file. It may be downloaded or opened in another tab',
loadInBrowserMsg: 'Open PDF File'+otMsg,
dropDownText: name ? `${name}${otMsg} (pdf file)` : undefined,
}
const {title,dropDownText,message,loadInBrowserMsg}= getBasicTitling(name,obsTitle,Format.PDF);
return dpdtDownload(title, url, 'download-0', 'pdf',
{ message, loadInBrowserMsg, dropDownText, }
);
}

export function makeHtmlEntry(url,name, obsTitle) {
const otMsg= makeOtMsg(obsTitle);
return dpdtDownload('Open', url, 'download-0', 'html',
{
message: 'This is a web page or web application. It can be open in another tab',
loadInBrowserMsg: 'Open Page'+otMsg,
dropDownText: name ? `${name}${otMsg} (html)` : undefined,
}
);
const {title,dropDownText,message,loadInBrowserMsg}= getBasicTitling(name,obsTitle,Format.HTML);
return dpdtDownload(title, url, 'download-0', 'html',
{ message, loadInBrowserMsg, dropDownText, } );
}

export function makeJsonEntry(url,name, obsTitle) {
const otMsg= makeOtMsg(obsTitle);
return dpdtText('Show JSON file'+otMsg, url, undefined,
{
dropDownText: name ? `${name}${otMsg} (JSON File)` : undefined,
fileType: 'json',
}
);
const {title,dropDownText}= getBasicTitling(name,obsTitle,Format.JSON);
return dpdtText(title, url, undefined, { dropDownText, fileType: 'json'});
}

export function makeTarEntry(url,name, obsTitle) {
const otMsg= makeOtMsg(obsTitle);
return dpdtDownload('Download TAR File'+otMsg, url, 'download-0', 'tar',
{
message: 'This is a TAR file. It may only be downloaded',
dropDownText: name ? `${name}${otMsg} (tar file)` : undefined,
}
);
const {title,dropDownText,message}= getBasicTitling(name,obsTitle,Format.TAR);
return dpdtDownload(title, url, 'download-0', 'tar', { message, dropDownText, } );
}

export function makeGzipEntry(url,name,obsTitle) {
const otMsg= makeOtMsg(obsTitle);
return dpdtDownload('Download GZip File'+otMsg, url, 'download-0', 'gzip',
{
message: 'This is a GZip file. It may only be downloaded',
dropDownText: name ? `${name}${otMsg} (GZip file)` : undefined,
}
);
const {title,dropDownText,message}= getBasicTitling(name,obsTitle,Format.GZIP);
return dpdtDownload(title, url, 'download-0', 'gzip', { message, dropDownText} );
}

export function makeAnyEntry(url,name, obsTitle) {
const otMsg= makeOtMsg(obsTitle);
const otMsg= makeObsTitleExtension(obsTitle);
return dpdtDownload('Download File'+otMsg, url, 'download-0', 'unknown',
{
message: 'This file may only only be downloaded',
Expand All @@ -310,70 +274,21 @@ export function makeAnyEntry(url,name, obsTitle) {
}

export function makePngEntry(url,name, obsTitle) {
const otMsg= makeOtMsg(obsTitle);
return dpdtPNG('Show PNG image'+otMsg,url,undefined,
{
dropDownText: name ? `${name}${otMsg} (image)` : undefined,
}
);
const {title,dropDownText}= getBasicTitling(name,obsTitle,Format.PNG);
return dpdtPNG(title,url,undefined, { dropDownText} );
}

export function makeTextEntry(url,name, obsTitle) {
const otMsg= makeOtMsg(obsTitle);
return dpdtText('Show text file'+otMsg,url, undefined,
{
dropDownText: name ? `${name}${otMsg} (Plain text file)` : undefined,
fileType: 'text',
}
);
const {title,dropDownText}= getBasicTitling(name,obsTitle,Format.TEXT);
return dpdtText(title,url, undefined, { dropDownText, fileType: 'text'} );
}


export function makeYamlEntry(url,name, obsTitle) {
const otMsg= makeOtMsg(obsTitle);
return dpdtText('Show yaml file'+otMsg,url,undefined,
{
dropDownText: name ? `${name}${otMsg} (Plain text file)` : undefined,
fileType: 'yaml',
}
);
const {title,dropDownText}= getBasicTitling(name,obsTitle,Format.YAML);
return dpdtText(title,url,undefined, { dropDownText, fileType: 'yaml', } );
}

const makeErrorResult= (message, fileName,url) =>
dpdtMessageWithDownload(`No displayable data available for this row${message?': '+message:''}`, fileName&&'Download: '+fileName, url);

export function createObsCoreImageTitle(table,row) {
// 1. try a template
const template= getDataServiceOptionByTable('productTitleTemplate',table);
if (template?.trim()==='') return ''; // setting template to empty string disables all title guessing
if (template) {
const templateColNames= template && getColNameFromTemplate(template);
const columns= getColumns(table);
if (templateColNames?.length && columns?.length) {
const cNames= columns.map( ({name}) => name);
const colObj= templateColNames.reduce((obj, v) => {
if (cNames.includes(v)) {
obj[v]= getCellValue(table,row,v);
}
return obj;
},{});
if (Object.keys(colObj).length===templateColNames.length) {
const titleStr= tokenSub(colObj,template);
if (titleStr) return titleStr;
}
}
}
// 2. try obs_title
if (getObsTitle(table,row)) return getObsTitle(table,row);

// 3. compute a name
let obsCollect= getCellValue(table,row,'obs_collection') || '';
const obsId= getCellValue(table,row,'obs_id') || '';
const iName= getCellValue(table,row,'instrument_name') || '';
if (obsCollect===iName) obsCollect= '';
return `${obsCollect?obsCollect+', ':''}${iName?iName+', ':''}${obsId}`;
}

function getColNameFromTemplate(template) {
return template.match(/\${[\w -.]+}/g)?.map( (s) => s.substring(2,s.length-1));
}
60 changes: 17 additions & 43 deletions src/firefly/js/metaConvert/PartAnalyzer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* License information at https://github.com/Caltech-IPAC/firefly/blob/master/License.txt
*/
import {isArray,isEmpty} from 'lodash';
import {getSSATitle, isSSATable} from '../voAnalyzer/TableAnalysis.js';
import {isSSATable} from '../voAnalyzer/TableAnalysis.js';
import {isFitsTableDataTypeNumeric} from '../visualize/FitsHeaderUtil.js';
import {getObsCoreData} from '../voAnalyzer/VoDataLinkServDef';
import {dpdtChartTable, dpdtImage, dpdtTable, DPtypes, SHOW_CHART, SHOW_TABLE} from './DataProductsType';
Expand All @@ -12,11 +12,13 @@ import {TitleOptions} from '../visualize/WebPlotRequest';
import {createChartTableActivate, createChartSingleRowArrayActivate, createTableExtraction, getExtractionText
} from './TableDataProductUtils.js';
import {createSingleImageActivate, createSingleImageExtraction} from './ImageDataProductsUtil';
import {getTableDropDownText, getAnalysisSSATitle, getAnalysisPartTableDataDesc} from './VoUITitles';

/**
*
* @param {Object} p
* @param {FileAnalysisPart} p.part
* @param {number} p.totalParts
* @param {WebPlotRequest} p.request
* @param {TableModel} p.table
* @param {number} p.row
Expand All @@ -26,23 +28,21 @@ import {createSingleImageActivate, createSingleImageExtraction} from './ImageDat
* @param {String} p.originalTitle
* @param {ActivateParams} p.activateParams
* @param {DataProductsFactoryOptions} p.options
* @param {String} p.title
* @return {{tableResult: DataProductsDisplayType|Array.<DataProductsDisplayType>|undefined, imageResult: DataProductsDisplayType|undefined}}
*/
export function analyzePart({part, request, table, row, fileFormat, dlData, originalTitle,
source, activateParams, options={}, title}) {
source, activateParams, totalParts, options={}}) {

const {type,desc, fileLocationIndex}= part;
const titleToUse= title ?? desc;
const aTypes= findAvailableTypesForAnalysisPart(part, fileFormat);
if (isEmpty(aTypes)) return {imageResult:false, tableResult:false};

const imageResult= aTypes.includes(DPtypes.IMAGE) && type===FileAnalysisType.Image &&
analyzeImageResult({part, request, table, row, fileFormat, dlData, source,
title:desc,activateParams,hduIdx:fileLocationIndex, originalTitle});
title:desc,activateParams,hduIdx:fileLocationIndex});

const tableResult= aTypes.includes(DPtypes.TABLE) &&
analyzeChartTableResult(table, row, part, fileFormat, source,titleToUse??desc,activateParams,options, originalTitle, dlData);
analyzeChartTableResult(table, row, part, fileFormat, source,desc,totalParts, activateParams,options, originalTitle);

return {imageResult, tableResult};
}
Expand Down Expand Up @@ -168,7 +168,7 @@ function getTableChartColInfo(title, part, fileFormat,table) {
if (part.tableDataType===TableDataType.Spectrum) {
tableDataType= TableDataType.Spectrum;
if (isSSATable(table)) {
showChartTitle= Boolean(getSSATitle(table,table.highlightedRow));
showChartTitle= Boolean(getAnalysisSSATitle(table,table.highlightedRow));
}
}
else if (isTimeSeries(colInfo)) {
Expand Down Expand Up @@ -215,35 +215,6 @@ function findMatchingUCDColumn(colInfo, testList) {
return colInfo.find( (ci) => ci.UCD?.toLowerCase().match(bestMatcher)?.[0]) ;
}

/**
*
* @param {String} title
* @param {String} originalTitle
* @param {FileAnalysisPart} part
* @param fileFormat
* @param {TableModel} table
* @return {string}
*/
function getTableDropTitleStr(title,originalTitle,part,fileFormat,table) {
if (!title) title='';
if (part.interpretedData) return title;
let endTitle;
if (fileFormat===Format.FITS) {
const tOrCStr= 'table or chart';
if (isImageAsTable(part,fileFormat)) {
const twoD= getImageAsTableColCount(part,fileFormat)>2;
const imageAsStr= twoD ? '2D image - show as ': '1D image - show as ';
endTitle= `HDU #${part.index} (${imageAsStr}${tOrCStr}${twoD? ' or image':''}) ${title}`;
}
else {
endTitle= `HDU #${part.index} (${tOrCStr}) ${title}`;
}
}
else {
endTitle= isSSATable(table) ? getSSATitle(table,table.highlightedRow) : `Part #${part.index} ${title}`;
}
return endTitle;
}


/**
Expand All @@ -254,32 +225,35 @@ function getTableDropTitleStr(title,originalTitle,part,fileFormat,table) {
* @param {String} fileFormat
* @param {String} source - server key to access the file
* @param {String} title
* @param {Number} totalParts
* @param {ActivateParams} activateParams
* @param {DataProductsFactoryOptions} options
* @param {String} originalTitle
* @param {DatalinkData} dlData
* @return {DataProductsDisplayType|undefined}
*/
function analyzeChartTableResult(table, row, part, fileFormat, source, title, activateParams,
options={}, originalTitle, dlData) {
function analyzeChartTableResult(table, row, part, fileFormat, source, title, totalParts, activateParams,
options={}, originalTitle) {
const {uiEntry,uiRender,interpretedData=false, fileLocationIndex:tbl_index=0}= part;
const partFormat= part.convertedFileFormat||fileFormat;
if (uiEntry===UIEntry.UseSpecified) {
if (uiRender!==UIRender.Chart) return undefined;
}
const {tbl_id,chartId}= getIds(options,title);

const ddTitleStr= getTableDropTitleStr(title,originalTitle, part,partFormat, table);
const dropDownText= originalTitle ? `${originalTitle} - ${ddTitleStr}` : ddTitleStr;

const useImageAsTable= partFormat===Format.FITS && isImageAsTable(part,partFormat);
const imageAsTableColCnt= useImageAsTable ? getImageAsTableColCount(part,fileFormat) : 0;
const ddTitleStr= getAnalysisPartTableDataDesc({title,part,fileFormat:partFormat, table, useImageAsTable, imageAsTableColCnt, totalParts});
const dropDownText= getTableDropDownText(originalTitle, ddTitleStr, totalParts);
const {chartInfo, imageAsTableInfo}= getTableChartColInfo(title, part, partFormat, table);

let titleInfo=title || `table_${part.index}`;
if (isSSATable(table)) titleInfo= getSSATitle(table,row)??'spectrum';
if (isSSATable(table)) titleInfo= getAnalysisSSATitle(table,row)??'spectrum';


if (chartInfo.hasChart) {
const chartTableDefOption= getChartTableDefaultOption(part,chartInfo,partFormat);
if (isSingleRowChart(part,partFormat,chartInfo)) { // a common case- single row table with array columns
if (isSingleRowChart(part,partFormat,chartInfo)) { // a common case: single row table with array columns
return makeSingleRowChartTableResult({ddTitleStr,source,activateParams,chartInfo,tbl_index, imageAsTableInfo,
chartTableDefOption, interpretedData, dropDownText});
}
Expand Down
9 changes: 5 additions & 4 deletions src/firefly/js/metaConvert/UploadAndAnalysis.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {createSingleImageActivate, createSingleImageExtraction} from './ImageDat
import {analyzePart} from './PartAnalyzer';
import {makeSingleDataProductWithMenu} from './vo/ObsCoreConverter.js';
import {makeUrlFromParams} from './vo/ServDescProducts.js';
import {getAnalysisAllImageDesc} from './VoUITitles';


const uploadedCache= {};
Expand Down Expand Up @@ -190,9 +191,9 @@ function makeAllImageEntry({request, path, parts, imageViewerId, dlData, tbl_id
newReq.setRequestType(RequestType.FILE);
parts.forEach( (p) => Object.entries(p.additionalImageParams ?? {} )
.forEach(([k,v]) => newReq.setParam(k,v)));
const title= request.getTitle() || '';
const name= getAnalysisAllImageDesc(parts,imagePartsLength);
const sourceObsCoreData= dlData ? dlData.sourceObsCoreData : getObsCoreData(getTblById(tbl_id),row);
return dpdtImage({name: `${title||'Image Data'} ${imagePartsLength>1? ': All Images in File' :''}`,
return dpdtImage({name,
dlData,
activate: createSingleImageActivate(newReq,imageViewerId,tbl_id,row),
extraction: createSingleImageExtraction(newReq, sourceObsCoreData, dlData),
Expand Down Expand Up @@ -252,12 +253,11 @@ function deeperInspection({ table, row, request, activateParams,
const rStr= request.toString();
const activeItemLookupKey= hashCode(rStr);
const fileMenu= {fileAnalysis, menu:[],activeItemLookupKey, activeItemLookupKeyOrigin:rStr};
const title= parts.length===1 ? originalTitle : undefined;

const partAnalysis= parts.map( (part) =>
analyzePart({part,request, table, row, fileFormat, originalTitle,
source: part.convertedFileName ?? serverCacheFileKey,
dlData, activateParams, options, title}));
dlData, activateParams, options, totalParts:parts.length}));
const imageParts= partAnalysis.filter( (pa) => pa.imageResult);
let makeAllImageOption= !disableAllImageOption;
if (makeAllImageOption) makeAllImageOption= imageParts.length>1 || (imageParts.length===1 && parts.length===1);
Expand Down Expand Up @@ -294,6 +294,7 @@ function deeperInspection({ table, row, request, activateParams,
m.analysisActivateFunc= analysisActivateFunc;
m.serDef= serDef;
m.originalTitle= originalTitle;
m.dropDownText= originalTitle ? originalTitle + ': ' + m.name : undefined;
});

fileMenu.initialDefaultIndex= 0;
Expand Down
Loading