Uploaded image for project: 'IGB'
  1. IGB
  2. IGBF-4209

Investigate: Use ChatGPT to make an IGB App

    Details

    • Type: Task
    • Status: Closed (View Workflow)
    • Priority: Major
    • Resolution: Done
    • Affects Version/s: None
    • Fix Version/s: None
    • Labels:
      None

      Description

      For this task, use ChatGPT to create a new IGB App.

      Record the prompts you used and also make note of how long it took you to make the App.

      Write about the experience in the comments and provide your code plus any other artifacts that seem relevant.

      The goal here is to do an exploratory pilot study of how difficult or easy it is to create a new IGB app now that coders have access to tools like ChatGPT and Github copilot.

        Attachments

          Activity

          ann.loraine Ann Loraine created issue -
          ann.loraine Ann Loraine made changes -
          Field Original Value New Value
          Epic Link IGBF-1531 [ 17617 ]
          ann.loraine Ann Loraine made changes -
          Summary Investigate: Use ChatGPT to make an IGB App asy
          Description For this task, use ChatGPT to create a new IGB App.

          Record the prompts you used and also make note of how long it took you to make the App.

          Write about the experience in the comments and provide your code plus any other artifacts that seem relevant.

          The goal here is to do an exploratory pilot study of how difficult or hard it is to create a new IGB app now that coders have access to tools like ChatGPT and Github copilot.
          For this task, use ChatGPT to create a new IGB App.

          Record the prompts you used and also make note of how long it took you to make the App.

          Write about the experience in the comments and provide your code plus any other artifacts that seem relevant.

          The goal here is to do an exploratory pilot study of how difficult or easy it is to create a new IGB app now that coders have access to tools like ChatGPT and Github copilot.
          pbhatia1 Pranav Bhatia (Inactive) made changes -
          Status To-Do [ 10305 ] In Progress [ 3 ]
          ann.loraine Ann Loraine made changes -
          Summary asy Investigate: Use ChatGPT to make an IGB App
          Hide
          pbhatia1 Pranav Bhatia (Inactive) added a comment - - edited

          As part of this exploratory study, I used ChatGPT to assist in building new IGB apps and assess the ease of development using LLM-based tools.

          Experience Summary: I started by discussing the “super-simple-igb-app” structure with ChatGPT. After confirming it was a minimal viable starter app for the Integrated Genome Browser, I asked:

          1. Whether users can use LLMs like ChatGPT to create IGB apps.
          2. How we can empower the public to create IGB plugins using AI.
          3. If ChatGPT could generate a working example IGB plugin for R&D purposes.

          ChatGPT provided detailed and relevant responses, suggesting multiple ways users could be supported via ChatGPT APIs and even proposed a plugin idea that displays a random genomics-related fact.

          I implemented the suggested app, and it worked successfully. The total time to set up, test, and verify this app was approximately 1 hour.

          Successful Outcome
          App Created: Displays a random genomics fact or quote upon clicking a menu item

          Unsuccessful Attempt: Next, I attempted to build a more complex app using ChatGPT: one that would take screenshots at user-defined intervals and compile them into a PDF.

          ChatGPT generated relevant code using PDDocument and PDImageXObject.

          However, the app failed to run in IGB, likely due to OSGi integration limitations.

          I spent 2–3 hours debugging but was ultimately unsuccessful in getting it to work within the IGB environment.

          Limitations: Complex apps requiring interaction with threads or background tasks still demand deeper knowledge of IGB internals and OSGi.

          Potential: With proper scaffolding tools or a custom GPT trained on IGB-specific documentation and examples, even non-expert developers could create functional IGB apps more easily.

          Artifacts Provided
          Working code for genomics fact plugin
          Prototype code for screenshot recorder plugin (non-functional)

          Facts app -

          package org.bioviz.igb.app;
          
          import org.osgi.service.component.annotations.Component;
          import java.util.Arrays;
          import java.util.List;
          import java.util.Optional;
          import java.util.Random;
          import javax.swing.JOptionPane;
          
          import org.lorainelab.igb.menu.api.MenuBarEntryProvider;
          import org.lorainelab.igb.menu.api.model.MenuBarParentMenu;
          import org.lorainelab.igb.menu.api.model.MenuItem;
          
          @Component(immediate = true)
          public class GenomicsFunApp implements MenuBarEntryProvider {
          
              private final List<String> facts = Arrays.asList(
                      "Did you know? The human genome contains about 3 billion base pairs.",
                      "Fun Fact: Mitochondrial DNA is inherited only from the mother.",
                      "Trivia: Only 1.5% of human DNA codes for proteins!",
                      "The first sequenced genome was that of a virus, in 1976."
              );
          
              @Override
              public Optional<List<MenuItem>> getMenuItems() {
                  MenuItem menuItem = new MenuItem("Random Genome Fact", (Void t) -> {
                      Random rand = new Random();
                      String fact = facts.get(rand.nextInt(facts.size()));
                      JOptionPane.showMessageDialog(null, fact);
                      return t;
                  });
                  menuItem.setWeight(1000000000);
                  return Optional.ofNullable(Arrays.asList(menuItem));
              }
          
              @Override
              public MenuBarParentMenu getMenuExtensionParent() {
                  return MenuBarParentMenu.TOOLS;
              }
          }
          
          

          Screenrecorder app -

          package org.bioviz.igb.app;
          
          import org.apache.pdfbox.pdmodel.PDDocument;
          import org.apache.pdfbox.pdmodel.PDPage;
          import org.apache.pdfbox.pdmodel.PDPageContentStream;
          import org.apache.pdfbox.pdmodel.common.PDRectangle;
          import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
          import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
          import org.osgi.service.component.annotations.Component;
          import org.lorainelab.igb.menu.api.MenuBarEntryProvider;
          import org.lorainelab.igb.menu.api.model.MenuBarParentMenu;
          import org.lorainelab.igb.menu.api.model.MenuItem;
          
          import javax.imageio.ImageIO;
          import javax.swing.*;
          import java.awt.*;
          import java.awt.image.BufferedImage;
          import java.io.File;
          import java.io.IOException;
          import java.util.*;
          import java.util.List;
          import java.util.concurrent.*;
          
          @Component(immediate = true)
          public class ScreenshotRecorderApp implements MenuBarEntryProvider {
          
              private ScheduledExecutorService scheduler;
              private List<File> screenshots = new ArrayList<>();
              private File outputDir = new File(System.getProperty("user.home"), "IGBSnapshots");
          
              @Override
              public Optional<List<MenuItem>> getMenuItems() {
                  MenuItem startItem = new MenuItem("Start Screenshot Recorder", (Void t) -> {
                      String input = JOptionPane.showInputDialog("Enter interval (in seconds):");
                      if (input == null) return t;
                      try {
                          int interval = Integer.parseInt(input.trim());
                          startRecording(interval);
                          JOptionPane.showMessageDialog(null, "Recording started. Use 'Stop Screenshot Recorder' to stop.");
                      } catch (NumberFormatException e) {
                          JOptionPane.showMessageDialog(null, "Invalid input. Please enter a number.");
                      }
                      return t;
                  });
          
                  MenuItem stopItem = new MenuItem("Stop Screenshot Recorder", (Void t) -> {
                      stopRecording();
                      return t;
                  });
          
                  return Optional.of(Arrays.asList(startItem, stopItem));
              }
          
              private void startRecording(int intervalSeconds) {
                  if (!outputDir.exists()) outputDir.mkdirs();
                  screenshots.clear();
          
                  scheduler = Executors.newSingleThreadScheduledExecutor();
                  scheduler.scheduleAtFixedRate(() -> {
                      try {
                          Robot robot = new Robot();
                          Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
                          BufferedImage screenFullImage = robot.createScreenCapture(screenRect);
                          File file = new File(outputDir, "screenshot_" + System.currentTimeMillis() + ".png");
                          ImageIO.write(screenFullImage, "png", file);
                          screenshots.add(file);
                          System.out.println("Screenshot taken: " + file.getAbsolutePath());
                      } catch (Exception e) {
                          e.printStackTrace();
                      }
                  }, 0, intervalSeconds, TimeUnit.SECONDS);
              }
          
              private void stopRecording() {
                  if (scheduler != null) {
                      scheduler.shutdown();
                      try {
                          if (!scheduler.awaitTermination(2, TimeUnit.SECONDS)) {
                              scheduler.shutdownNow();
                          }
                      } catch (InterruptedException e) {
                          scheduler.shutdownNow();
                      }
                  }
          
                  try {
                      File pdfFile = new File(outputDir, "IGB_Screenshots_" + System.currentTimeMillis() + ".pdf");
                      PDDocument doc = new PDDocument();
                      for (File imageFile : screenshots) {
                          BufferedImage bimg = ImageIO.read(imageFile);
                          PDPage page = new PDPage(new PDRectangle(bimg.getWidth(), bimg.getHeight()));
                          doc.addPage(page);
                          PDImageXObject pdImage = LosslessFactory.createFromImage(doc, bimg);
                          PDPageContentStream contentStream = new PDPageContentStream(doc, page);
                          contentStream.drawImage(pdImage, 0, 0);
                          contentStream.close();
                      }
                      doc.save(pdfFile);
                      doc.close();
                      JOptionPane.showMessageDialog(null, "PDF created: " + pdfFile.getAbsolutePath());
                  } catch (IOException e) {
                      JOptionPane.showMessageDialog(null, "Error creating PDF: " + e.getMessage());
                  }
              }
          
              @Override
              public MenuBarParentMenu getMenuExtensionParent() {
                  return MenuBarParentMenu.TOOLS;
              }
          }
          
          
          Show
          pbhatia1 Pranav Bhatia (Inactive) added a comment - - edited As part of this exploratory study, I used ChatGPT to assist in building new IGB apps and assess the ease of development using LLM-based tools. Experience Summary: I started by discussing the “super-simple-igb-app” structure with ChatGPT. After confirming it was a minimal viable starter app for the Integrated Genome Browser, I asked: Whether users can use LLMs like ChatGPT to create IGB apps. How we can empower the public to create IGB plugins using AI. If ChatGPT could generate a working example IGB plugin for R&D purposes. ChatGPT provided detailed and relevant responses, suggesting multiple ways users could be supported via ChatGPT APIs and even proposed a plugin idea that displays a random genomics-related fact. I implemented the suggested app, and it worked successfully. The total time to set up, test, and verify this app was approximately 1 hour. Successful Outcome App Created: Displays a random genomics fact or quote upon clicking a menu item Unsuccessful Attempt: Next, I attempted to build a more complex app using ChatGPT: one that would take screenshots at user-defined intervals and compile them into a PDF. ChatGPT generated relevant code using PDDocument and PDImageXObject. However, the app failed to run in IGB, likely due to OSGi integration limitations. I spent 2–3 hours debugging but was ultimately unsuccessful in getting it to work within the IGB environment. Limitations: Complex apps requiring interaction with threads or background tasks still demand deeper knowledge of IGB internals and OSGi. Potential: With proper scaffolding tools or a custom GPT trained on IGB-specific documentation and examples, even non-expert developers could create functional IGB apps more easily. Artifacts Provided Working code for genomics fact plugin Prototype code for screenshot recorder plugin (non-functional) Facts app - package org.bioviz.igb.app; import org.osgi.service.component.annotations.Component; import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.Random; import javax.swing.JOptionPane; import org.lorainelab.igb.menu.api.MenuBarEntryProvider; import org.lorainelab.igb.menu.api.model.MenuBarParentMenu; import org.lorainelab.igb.menu.api.model.MenuItem; @Component(immediate = true ) public class GenomicsFunApp implements MenuBarEntryProvider { private final List< String > facts = Arrays.asList( "Did you know? The human genome contains about 3 billion base pairs." , "Fun Fact: Mitochondrial DNA is inherited only from the mother." , "Trivia: Only 1.5% of human DNA codes for proteins!" , "The first sequenced genome was that of a virus, in 1976." ); @Override public Optional<List<MenuItem>> getMenuItems() { MenuItem menuItem = new MenuItem( "Random Genome Fact" , ( Void t) -> { Random rand = new Random(); String fact = facts.get(rand.nextInt(facts.size())); JOptionPane.showMessageDialog( null , fact); return t; }); menuItem.setWeight(1000000000); return Optional.ofNullable(Arrays.asList(menuItem)); } @Override public MenuBarParentMenu getMenuExtensionParent() { return MenuBarParentMenu.TOOLS; } } Screenrecorder app - package org.bioviz.igb.app; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory; import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; import org.osgi.service.component.annotations.Component; import org.lorainelab.igb.menu.api.MenuBarEntryProvider; import org.lorainelab.igb.menu.api.model.MenuBarParentMenu; import org.lorainelab.igb.menu.api.model.MenuItem; import javax.imageio.ImageIO; import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.*; import java.util.List; import java.util.concurrent.*; @Component(immediate = true ) public class ScreenshotRecorderApp implements MenuBarEntryProvider { private ScheduledExecutorService scheduler; private List<File> screenshots = new ArrayList<>(); private File outputDir = new File( System .getProperty( "user.home" ), "IGBSnapshots" ); @Override public Optional<List<MenuItem>> getMenuItems() { MenuItem startItem = new MenuItem( "Start Screenshot Recorder" , ( Void t) -> { String input = JOptionPane.showInputDialog( "Enter interval (in seconds):" ); if (input == null ) return t; try { int interval = Integer .parseInt(input.trim()); startRecording(interval); JOptionPane.showMessageDialog( null , "Recording started. Use 'Stop Screenshot Recorder' to stop." ); } catch (NumberFormatException e) { JOptionPane.showMessageDialog( null , "Invalid input. Please enter a number." ); } return t; }); MenuItem stopItem = new MenuItem( "Stop Screenshot Recorder" , ( Void t) -> { stopRecording(); return t; }); return Optional.of(Arrays.asList(startItem, stopItem)); } private void startRecording( int intervalSeconds) { if (!outputDir.exists()) outputDir.mkdirs(); screenshots.clear(); scheduler = Executors.newSingleThreadScheduledExecutor(); scheduler.scheduleAtFixedRate(() -> { try { Robot robot = new Robot(); Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()); BufferedImage screenFullImage = robot.createScreenCapture(screenRect); File file = new File(outputDir, "screenshot_" + System .currentTimeMillis() + ".png" ); ImageIO.write(screenFullImage, "png" , file); screenshots.add(file); System .out.println( "Screenshot taken: " + file.getAbsolutePath()); } catch (Exception e) { e.printStackTrace(); } }, 0, intervalSeconds, TimeUnit.SECONDS); } private void stopRecording() { if (scheduler != null ) { scheduler.shutdown(); try { if (!scheduler.awaitTermination(2, TimeUnit.SECONDS)) { scheduler.shutdownNow(); } } catch (InterruptedException e) { scheduler.shutdownNow(); } } try { File pdfFile = new File(outputDir, "IGB_Screenshots_" + System .currentTimeMillis() + ".pdf" ); PDDocument doc = new PDDocument(); for (File imageFile : screenshots) { BufferedImage bimg = ImageIO.read(imageFile); PDPage page = new PDPage( new PDRectangle(bimg.getWidth(), bimg.getHeight())); doc.addPage(page); PDImageXObject pdImage = LosslessFactory.createFromImage(doc, bimg); PDPageContentStream contentStream = new PDPageContentStream(doc, page); contentStream.drawImage(pdImage, 0, 0); contentStream.close(); } doc.save(pdfFile); doc.close(); JOptionPane.showMessageDialog( null , "PDF created: " + pdfFile.getAbsolutePath()); } catch (IOException e) { JOptionPane.showMessageDialog( null , "Error creating PDF: " + e.getMessage()); } } @Override public MenuBarParentMenu getMenuExtensionParent() { return MenuBarParentMenu.TOOLS; } }
          pbhatia1 Pranav Bhatia (Inactive) made changes -
          Status In Progress [ 3 ] Needs 1st Level Review [ 10005 ]
          pbhatia1 Pranav Bhatia (Inactive) made changes -
          Assignee Pranav Bhatia [ pbhatia1 ]
          pbhatia1 Pranav Bhatia (Inactive) made changes -
          Attachment Prompts-IGB-Apps-R&D.pdf [ 18686 ]
          Hide
          pbhatia1 Pranav Bhatia (Inactive) added a comment -

          Attached PDF contains the prompt questions and my responses generated using ChatGPT.

          Prompts-IGB-Apps-R&D.pdf

          Link to repository for Screenrecorder App - https://bitbucket.org/pranavbhatia1999/screenrecorder-app/src/master/

          Link to repository for Genomics Fun Facts App - https://bitbucket.org/pranavbhatia1999/genomics-fun-app/src/master/

          Show
          pbhatia1 Pranav Bhatia (Inactive) added a comment - Attached PDF contains the prompt questions and my responses generated using ChatGPT. Prompts-IGB-Apps-R&D.pdf Link to repository for Screenrecorder App - https://bitbucket.org/pranavbhatia1999/screenrecorder-app/src/master/ Link to repository for Genomics Fun Facts App - https://bitbucket.org/pranavbhatia1999/genomics-fun-app/src/master/
          ann.loraine Ann Loraine made changes -
          Status Needs 1st Level Review [ 10005 ] First Level Review in Progress [ 10301 ]
          ann.loraine Ann Loraine made changes -
          Status First Level Review in Progress [ 10301 ] Ready for Pull Request [ 10304 ]
          ann.loraine Ann Loraine made changes -
          Status Ready for Pull Request [ 10304 ] Pull Request Submitted [ 10101 ]
          ann.loraine Ann Loraine made changes -
          Status Pull Request Submitted [ 10101 ] Reviewing Pull Request [ 10303 ]
          ann.loraine Ann Loraine made changes -
          Status Reviewing Pull Request [ 10303 ] Merged Needs Testing [ 10002 ]
          ann.loraine Ann Loraine made changes -
          Status Merged Needs Testing [ 10002 ] Post-merge Testing In Progress [ 10003 ]
          ann.loraine Ann Loraine made changes -
          Resolution Done [ 10000 ]
          Status Post-merge Testing In Progress [ 10003 ] Closed [ 6 ]
          ann.loraine Ann Loraine made changes -
          Assignee Pranav Bhatia [ pbhatia1 ]

            People

            • Assignee:
              pbhatia1 Pranav Bhatia (Inactive)
              Reporter:
              ann.loraine Ann Loraine
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: