c56be670aa15932c81d5a1b751af166e0e26b2be
markd
  Tue Dec 30 12:49:16 2025 -0800
allow pslMap to remotely access chain psl input file

diff --git src/utils/pslMap/pslMap.c src/utils/pslMap/pslMap.c
index 0f3d122992d..ee716eeab40 100644
--- src/utils/pslMap/pslMap.c
+++ src/utils/pslMap/pslMap.c
@@ -1,29 +1,30 @@
 /* pslMap - map PSLs alignments to new targets using alignments of the old
  * target to the new target. */
 
 /* Copyright (C) 2014 The Regents of the University of California 
  * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */
 #include "common.h"
 #include "pslTransMap.h"
 #include "options.h"
 #include "linefile.h"
 #include "genomeRangeTree.h"
 #include "dystring.h"
 #include "psl.h"
 #include "dnautil.h"
 #include "chain.h"
+#include "net.h"
 #include "verbose.h"
 
 
 /* command line option specifications */
 static struct optionSpec optionSpecs[] = {
     {"suffix", OPTION_STRING},
     {"keepTranslated", OPTION_BOOLEAN},
     {"mapFileWithInQName", OPTION_BOOLEAN},
     {"check", OPTION_BOOLEAN},
     {"chainMapFile", OPTION_BOOLEAN},
     {"swapMap", OPTION_BOOLEAN},
     {"swapIn", OPTION_BOOLEAN},
     {"mapInfo", OPTION_STRING},
     {"tsv", OPTION_BOOLEAN},
     {"mappingPsls", OPTION_STRING},
@@ -178,31 +179,35 @@
     psl->tStarts[iBlk] = cBlk->tStart;
     psl->match += psl->blockSizes[iBlk];
     psl->blockCount++;
     }
 pslComputeInsertCounts(psl);
 if (swapMap)
     pslSwap(psl, FALSE);
 return mapAlnNew(psl, ch->id, NULL);
 }
 
 static struct genomeRangeTree* loadMapChains(char *chainFile)
 /* read a chain file, convert to mapAln object and genomeRangeTree by query locations. */
 {
 struct genomeRangeTree* mapAlns = genomeRangeTreeNew();
 struct chain *ch;
-struct lineFile *chLf = lineFileOpen(chainFile, TRUE);
+struct lineFile *chLf;
+if (udcIsLocal(chainFile))
+    chLf = lineFileOpen(chainFile, TRUE);
+else
+    chLf = netLineFileOpen(chainFile);
 while ((ch = chainRead(chLf)) != NULL)
     {
     struct mapAln* mapAln = chainToPsl(ch);
     mapAlnsAdd(mapAlns, mapAln->psl->qName, mapAln);
     chainFree(&ch);
     }
 lineFileClose(&chLf);
 return mapAlns;
 }
 
 static struct mapAln* readPslMapAln(struct lineFile *pslLf, int id)
 /* read the next mapping PSL, handling optional qName.  Return NULL on EOF */
 {
 char *words[32];
 int wordCount = lineFileChopNextTab(pslLf, words, ArraySize(words));
@@ -220,31 +225,35 @@
              wordCount, 21+pslOffset, 23+pslOffset,
              (mapFileWithInQName ? " (including -mapFileWithInQName extra column)" : ""));
 if (swapMap)
     pslSwap(psl, FALSE);
 return mapAlnNew(psl, id, mapFileWithInQName ? words[0] : NULL);
 }
 
 static struct genomeRangeTree* loadMapPsls(char *pslFile)
 /* read a psl file and genomeRangeTree by query, linking multiple PSLs for the
  * same query.*/
 {
 struct dyString* idBuf = NULL;
 struct genomeRangeTree* mapAlns = genomeRangeTreeNew();
 int id = 0;
 struct mapAln* mapAln;
-struct lineFile *pslLf = lineFileOpen(pslFile, TRUE);
+struct lineFile *pslLf;
+if (udcIsLocal(pslFile))
+    pslLf = lineFileOpen(pslFile, TRUE);
+else
+    pslLf = netLineFileOpen(pslFile);
 while ((mapAln = readPslMapAln(pslLf, id)) != NULL)
     {
     mapAlnsAdd(mapAlns, getMappingId(mapAln->psl->qName, &idBuf), mapAln);
     id++;
     }
 lineFileClose(&pslLf);
 dyStringFree(&idBuf);
 return mapAlns;
 }
 
 static int pslAlignedBases(struct psl *psl)
 /* get number of aligned bases in a psl.  Need because we can't set the stats
  * in the mapped psl */
 {
 int i, cnt = 0;
@@ -364,31 +373,35 @@
             {
             if (mapPslPair(inPsl, overMapAln, outPslFh, mapInfoFh, mappingPslFh, outPslLineRef))
                 wasMapped = TRUE;
             }
         }
     }
 if ((mapInfoFh != NULL) && !wasMapped)
     writeMapInfo(mapInfoFh, inPsl, NULL, NULL, 0);
 }
 
 static void pslMap(char* inPslFile, char *mapFile, char *outPslFile)
 /* project inPsl query through mapFile query to mapFile target */
 {
 struct genomeRangeTree *mapAlns;
 struct psl* inPsl;
-struct lineFile* inPslLf = pslFileOpen(inPslFile);
+struct lineFile* inPslLf;
+if (udcIsLocal(inPslFile))
+    inPslLf = lineFileOpen(inPslFile, TRUE);
+else
+    inPslLf = netLineFileOpen(inPslFile);
 FILE *outPslFh, *mapInfoFh = NULL, *mappingPslFh = NULL;
 unsigned outPslLine = 0;
 
 if (chainMapFile)
     mapAlns = loadMapChains(mapFile);
 else
     mapAlns = loadMapPsls(mapFile);
 
 outPslFh = mustOpen(outPslFile, "w");
 if (mapInfoFile != NULL)
     {
     mapInfoFh = mustOpen(mapInfoFile, "w");
     if (!tsv)
         fputc('#', mapInfoFh);
     fputs(mapInfoHdr, mapInfoFh);