RAPID Pipeline Development #################################################### Increasing AWS Cloud Limits ************************************ Submit a ticket to the IPAC Support Group (ISG) requesting an AWS increase in the relevant limit for the RAPID project (this involves Wendy submitting a ticket to AWS). `ISG Request URL `_ Login with your IPAC credentials (not sure whether VPN must be running). Development Guidelines ************************************ #. Set up your text editor to clip trailing spaces when saving source-code file (e.g., BBEdit has a setting that does this). #. Ensure no tab characters are used for indentation in your Python code; use spaces always (e.g., BBEdit has a setting that does this). #. Think strategically when pushing a source-code file to the git repo whether a simple git diff between revisions will allow a clear and unambiguous indication of the code changes. For example, numerous stylistic changes can hide substantive changes that affect code behavior and should be deferred to a separate revision. #. Before checking into the git repo modifications to someone else's source code, let that person know what to expect (and assure there is the expected level of trust beforehand). #. Your git commits should have self-explanatory descriptive messages (saves time not having to review source code later for reports). #. Always test code changes before the code is put into operations; the development is not done until the code changes have been tested. #. Include a sufficiency of comments in your source code! #. Remember to ``git pull`` before any ``git push`` and often, in order to make sure your RAPID git repo is up to date. #. For exitcodes, we follow the Spitzer convention: ============== ================ Exitcode range Definition ============== ================ [0,31] Normal termination, with messages [32,61] Warnings [64+] Error ============== ================ GitHub Merging, Branching, and Pull Requests ******************************************** This section describes the recommended git workflow for contributing to the RAPID code base. .. note:: Pending approval of the team, we will be migrating to a ``dev`` branch workflow and **disabling direct pushes to** ``main``. Once this is in effect, all routine development will target ``dev``, and changes will reach ``main`` only through pull requests. The instructions below assume this workflow. GitHub Branches ============================================ The RAPID repository follows a two-branch model: * ``main`` — the stable, production branch. Direct pushes will be disabled; it is updated only via approved pull requests. * ``dev`` — the active development branch. Day-to-day work lands here. The general rule of thumb: **small changes can go straight to** ``dev``, while **large changes or new features get their own branch** off ``dev`` and can be merged back via a pull request. The diagram below illustrates the full flow: a feature branch off ``dev``, two commits of work, a pull request merging the feature back into ``dev``, and ``dev`` later merging into ``main``. .. figure:: code_astro_feature_graph.png :width: 600 :alt: Git graph: feature branch off dev, PR back to dev, then dev merged to main Source: `Code/Astro Workshop `__ Small Changes ============================================ Small, low-risk changes (a bug fix, a comment, a one-line tweak) can be pushed directly to ``dev``. The basic cycle is **pull, commit, push**: .. code-block:: bash git pull git add git commit -m "Describe your change" git push If you have unsaved changes and ``git pull`` reports a conflict, stash your changes, pull, then re-apply your stash: .. code-block:: bash git stash git pull git stash pop After ``git stash pop``, resolve any conflicts that git reports (see merge conflicts, below), then commit and push as above. If you have a local commit that conflicts with a pulled commit, causing ``git pull`` to fail: .. code-block:: bash git pull --rebase This will move HEAD to the latest commit from the remote branch and replay your changes on top. Resolve the merge conflict (see below), and run: .. code-block:: bash git add git rebase --continue Large Changes / Feature Additions ============================================ For larger changes or new features, create a dedicated branch off ``dev`` so that work-in-progress does not destabilize the shared branch. Create a branch from ``dev`` -------------------------------------------- If you are already on ``dev``, create and switch to a new branch: .. code-block:: bash git checkout -b my_branch # or git checkout -b my_branch dev # if you are on another branch Then push the branch to GitHub and set it to track the remote, so that future ``git push`` / ``git pull`` commands work without extra arguments: .. code-block:: bash git push -u origin my_branch After this, make commits as normal to your new branch. Open a Pull Request back to ``dev`` -------------------------------------------- When you are done with your feature branch or have completed major changes, open a pull request on GitHub to merge it into ``dev``: 1. Push your latest commits (``git push``). 2. On GitHub, navigate to the repository. A banner usually appears offering to **Compare & pull request** for your recently pushed branch — click it. Otherwise, go to the **Pull requests** tab and click **New pull request**. .. image:: pull_request_open.png :width: 600 :alt: GitHub Compare & pull request banner 3. Set the **base** branch to ``dev`` and the **compare** branch to ``my_branch``. Double-check that the base is ``dev`` and **not** ``main``. 4. Give the PR a descriptive title and summary, then click **Create pull request**. .. image:: pull_request_create.png :width: 600 :alt: Selecting base=dev and compare=my_branch 5. Request a reviewer if required, and address any review comments by pushing additional commits to ``my_branch`` (the PR updates automatically). 6. Once approved, click **Merge pull request** to merge into ``dev``. .. image:: pull_request_merge.png :width: 600 :alt: Merge pull request button Close the branch after merging (optional) -------------------------------------------- Once the pull request is merged, if you are finished editing a particular feature, delete the branch to keep the repository tidy. On GitHub, click the **Delete branch** button shown on the merged pull request. To delete the branch locally and on the remote from the command line: .. code-block:: bash git checkout dev git pull git branch -d my_branch git push origin --delete my_branch The ``git pull`` on ``dev`` brings in your just-merged changes. Use ``git branch -d`` (lowercase) to delete only a branch that has been fully merged; ``git branch -D`` (uppercase) forces deletion of an unmerged branch, so use it with care. Merging changes from ``dev`` -------------------------------------------- If ``dev`` has moved ahead and you need those changes in your branch, fetch the latest refs and merge ``dev`` into your branch: .. code-block:: bash git fetch origin git merge origin/dev Resolve any conflicts git reports, then commit the merge and push: .. code-block:: bash git add git commit git push Resolving Merge Conflicts ============================================ A conflict happens when two changes touch the same lines of a file and git cannot decide which to keep. This can come up after any of the operations above. Git will report which files conflicted, for example:: Auto-merging pipeline.py CONFLICT (content): Merge conflict in pipeline.py Automatic merge failed; fix conflicts and then commit the result. You can always list the files that still need attention: .. code-block:: bash git status Conflicted files are shown under **"Unmerged paths"**. Editing the conflict markers -------------------------------------------- Open each conflicted file. Git inserts markers around the disagreeing sections: .. code-block:: text <<<<<<< HEAD your version of the lines ======= the incoming version of the lines >>>>>>> origin/dev The block above ``=======`` is your current branch's version (``HEAD``); the block below is the incoming version (here, ``origin/dev``). Edit the file so it contains exactly what you want the final result to be, and **delete all three marker lines** (``<<<<<<<``, ``=======``, ``>>>>>>>``). .. note:: VS Code makes this easier: it highlights each conflict and offers **Accept Current Change**, **Accept Incoming Change**, **Accept Both Changes**, or **Compare Changes** buttons directly above the conflict. Click the one you want, or edit manually, then save the file. Completing the merge -------------------------------------------- Once a file looks correct, stage it to mark the conflict resolved, then repeat for every conflicted file: .. code-block:: bash git add When ``git status`` shows no remaining unmerged paths, finish the operation: * After a **merge** or **stash pop**, commit the result: .. code-block:: bash git commit * After a **pull** that started a rebase, continue it instead: .. code-block:: bash git rebase --continue Then push as usual. Bailing out -------------------------------------------- If things get tangled and you want to start over, you can abort and return to the state before the operation began: .. code-block:: bash git merge --abort # during a conflicted merge git rebase --abort # during a conflicted rebase If you applied a stash with ``git stash pop`` and want to undo it, note that ``pop`` removes the stash once applied; use ``git stash apply`` instead when you want to keep the stash entry around as a safety net while resolving. Log into EC2 Instance Machine ******************************************** This assumes you have already set up an EC2 instance under the AWS console, and that the EC2 instance is stopped. Also, a key pair has been assigned to the EC2 instance, and the private key is installed in a ``.pem`` file on your laptop. 1. Ensure the following environment variables are set on your laptop: .. code-block:: AWS_DEFAULT_REGION AWS_SECRET_ACCESS_KEY AWS_EC2_INSTANCE_ID AWS_ACCESS_KEY_ID AWS_EC2_VOLUME_ID AWS_EC2_VOLUME_DEVICE The two latter ones are only needed if your EC2 instance is to have an EBS volume attached. Your EC2 instance should have a large enough book-disk volume as ``docker build`` requires a lot of space; at least 32 GB is recommended. 2. Ensure python3 is installed on your laptop and restart your EC2 instance: .. code-block:: python /source-code/location/rapid/aws/start_ec2_instance.py Here is how to stop your EC2 instance later: .. code-block:: python /source-code/location/rapid/aws/stop_ec2_instance.py 3. Log into your EC2 instance: .. code-block:: ssh -i ~/.ssh/my_ec2.pem ubuntu@ec2-54-212-213-65.us-west-2.compute.amazonaws.com Build Docker Image for RAPID Science Pipeline ********************************************* Check your latest source-code changes into the RAPID git repo. Under root on your EC2 instance, check out the latest source code from the RAPID git repo, and then build the Docker image for the RAPID pipeline: .. code-block:: sudo su cd /home/ubuntu/rapid git pull The following command removes ALL Docker images from your EC2 instance, but has the advantage of removing all Docker debris from the boot-disk volume, thus reclaiming disk space: .. code-block:: docker system prune -a -f .. warning:: The above ``docker system prune`` command and the ``docker build`` command below will not work properly or as intended, meaning the expected disk space will not be reclaimed, unless all containers running the Docker image ``rapid_science_pipeline:1.0`` are stopped! Here is how to get a listing of your Docker containers that are running: .. code-block:: docker ps Here is how to get a listing of your Docker images: .. code-block:: docker image ls Rebuild the Docker image from scratch: .. code-block:: cd /home/ubuntu/rapid docker build --build-arg RAPID_BRANCH= --file /home/ubuntu/rapid/docker/Dockerfile_ubuntu_runSingleSciencePipeline --tag rapid_science_pipeline:1.0 . Push Docker image to the Amazon public elastic container registry (ECR): Note that the RAPID-pipeline image has already been registered at .. code-block:: public.ecr.aws/y9b1s7h8/rapid_science_pipeline and so this step involves simply updating the Docker image in the registry. Authenticate your Docker client to the registry as follows: .. code-block:: aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/y9b1s7h8 Now get the Docker image ID as follows: .. code-block:: docker image ls The response will be something like: .. code-block:: REPOSITORY TAG IMAGE ID CREATED SIZE rapid_science_pipeline 1.0 a76b1373bfe2 6 minutes ago 2.36GB Tag the Docker image with "latest" and push to ECR with these two commands: .. code-block:: docker tag a76b1373bfe2 public.ecr.aws/y9b1s7h8/rapid_science_pipeline:latest docker push public.ecr.aws/y9b1s7h8/rapid_science_pipeline:latest Running an Instance of the RAPID Science Pipeline under AWS Batch ***************************************************************** The following shows commands to launch an instance of the RAPID science pipeline as AWS Batch job. The to-be-run-under-AWS-Batch Docker container rapid_science_pipeline:1.0 has /code built in, so there is no need to mount an external volume for /code. The container name is arbitrary, and is set to "russ-test-jobsubmit" in the example below. Since this Docker image contains the ENTRYPOINT instruction, you must override it with the ``--entrypoint bash`` option (and do not put ``bash`` at the end of the command). .. code-block:: mkdir -p /home/ubuntu/work/test_20250314 cd /home/ubuntu/work/test_20250314 aws s3 cp s3://rapid-pipeline-files/roman_tessellation_nside512.db /home/ubuntu/work/test_20250314/roman_tessellation_nside512.db sudo su docker stop russ-test-jobsubmit docker rm russ-test-jobsubmit docker run -it --entrypoint bash --name russ-test-jobsubmit -v /home/ubuntu/work/test_20250314:/work public.ecr.aws/y9b1s7h8/rapid_science_pipeline:latest export DBPORT=5432 export DBNAME=rapidopsdb export DBUSER=rapidporuss export DBSERVER=35.165.53.98 export DBPASS="????" export AWS_DEFAULT_REGION=us-west-2 export AWS_SECRET_ACCESS_KEY=???? export AWS_ACCESS_KEY_ID=???? export LD_LIBRARY_PATH=/code/c/lib export PATH=/code/c/bin:$PATH export export RAPID_SW=/code export export RAPID_WORK=/work export PYTHONPATH=/code export PYTHONUNBUFFERED=1 git config --global --add safe.directory /code cd /tmp export ROMANTESSELLATIONDBNAME=/work/roman_tessellation_nside512.db export RID=172211 python3.11 /code/pipeline/awsBatchSubmitJobs_launchSingleSciencePipeline.py exit Python 3.11 is required and it is installed inside the Docker image (/usr/bin/python3.11). After the AWS Batch job finishes, there are files written to S3 buckets that can be examined: .. code-block:: aws s3 ls --recursive s3://rapid-pipeline-files/20250314/ | grep jid1\\. 2025-03-14 11:22:33 3784 20250314/input_images_for_refimage_jid1.csv 2025-03-14 11:22:33 14307 20250314/job_config_jid1.ini .. code-block:: aws s3 ls --recursive s3://rapid-pipeline-logs/20250314/ | grep jid1_ 2025-03-14 11:28:38 207277 20250314/rapid_pipeline_job_20250314_jid1_log.txt .. code-block:: aws s3 ls --recursive s3://rapid-product-files/20250314/jid1/ 2025-03-14 11:24:03 21813719 20250314/jid1/Roman_TDS_simple_model_F184_1856_2_lite.fits.gz 2025-03-14 11:26:59 66888000 20250314/jid1/Roman_TDS_simple_model_F184_1856_2_lite_reformatted.fits 2025-03-14 11:27:01 66888000 20250314/jid1/Roman_TDS_simple_model_F184_1856_2_lite_reformatted_pv.fits 2025-03-14 11:27:00 66888000 20250314/jid1/Roman_TDS_simple_model_F184_1856_2_lite_reformatted_unc.fits 2025-03-14 11:26:14 196004160 20250314/jid1/awaicgen_output_mosaic_cov_map.fits 2025-03-14 11:27:03 66890880 20250314/jid1/awaicgen_output_mosaic_cov_map_resampled.fits 2025-03-14 11:26:36 196007040 20250314/jid1/awaicgen_output_mosaic_image.fits 2025-03-14 11:27:02 66890880 20250314/jid1/awaicgen_output_mosaic_image_resampled.fits 2025-03-14 11:28:34 133770240 20250314/jid1/awaicgen_output_mosaic_image_resampled_gainmatched.fits 2025-03-14 11:27:17 1248727 20250314/jid1/awaicgen_output_mosaic_image_resampled_refgainmatchsexcat.txt 2025-03-14 11:26:30 3465552 20250314/jid1/awaicgen_output_mosaic_refimsexcat.txt 2025-03-14 11:26:43 196007040 20250314/jid1/awaicgen_output_mosaic_uncert_image.fits 2025-03-14 11:27:04 66890880 20250314/jid1/awaicgen_output_mosaic_uncert_image_resampled.fits 2025-03-14 11:28:33 66890880 20250314/jid1/bkg_subbed_science_image.fits 2025-03-14 11:27:17 436195 20250314/jid1/bkg_subbed_science_image_scigainmatchsexcat.txt 2025-03-14 11:28:30 66890880 20250314/jid1/diffimage_masked.fits 2025-03-14 11:28:32 148657 20250314/jid1/diffimage_masked.txt 2025-03-14 11:28:36 216901 20250314/jid1/diffimage_masked_psfcat.txt 2025-03-14 11:28:36 66885120 20250314/jid1/diffimage_masked_psfcat_residual.fits 2025-03-14 11:28:31 66888000 20250314/jid1/diffimage_uncert_masked.fits 2025-03-14 11:28:32 28800 20250314/jid1/diffpsf.fits 2025-03-14 09:19:39 66853440 20250314/jid1/refiminputs/Roman_TDS_simple_model_F184_1087_7_lite_reformatted.fits 2025-03-14 09:19:51 66853440 20250314/jid1/refiminputs/Roman_TDS_simple_model_F184_1087_7_lite_reformatted_unc.fits 2025-03-14 09:19:43 66853440 20250314/jid1/refiminputs/Roman_TDS_simple_model_F184_1087_8_lite_reformatted.fits 2025-03-14 09:19:56 66853440 20250314/jid1/refiminputs/Roman_TDS_simple_model_F184_1087_8_lite_reformatted_unc.fits 2025-03-14 09:19:42 66853440 20250314/jid1/refiminputs/Roman_TDS_simple_model_F184_1476_11_lite_reformatted.fits 2025-03-14 09:19:55 66853440 20250314/jid1/refiminputs/Roman_TDS_simple_model_F184_1476_11_lite_reformatted_unc.fits 2025-03-14 09:19:34 66853440 20250314/jid1/refiminputs/Roman_TDS_simple_model_F184_1476_14_lite_reformatted.fits 2025-03-14 09:19:46 66853440 20250314/jid1/refiminputs/Roman_TDS_simple_model_F184_1476_14_lite_reformatted_unc.fits 2025-03-14 09:19:41 66853440 20250314/jid1/refiminputs/Roman_TDS_simple_model_F184_1481_16_lite_reformatted.fits 2025-03-14 09:19:54 66853440 20250314/jid1/refiminputs/Roman_TDS_simple_model_F184_1481_16_lite_reformatted_unc.fits 2025-03-14 09:19:35 66853440 20250314/jid1/refiminputs/Roman_TDS_simple_model_F184_317_9_lite_reformatted.fits 2025-03-14 09:19:47 66853440 20250314/jid1/refiminputs/Roman_TDS_simple_model_F184_317_9_lite_reformatted_unc.fits 2025-03-14 09:19:38 66853440 20250314/jid1/refiminputs/Roman_TDS_simple_model_F184_322_2_lite_reformatted.fits 2025-03-14 09:19:50 66853440 20250314/jid1/refiminputs/Roman_TDS_simple_model_F184_322_2_lite_reformatted_unc.fits 2025-03-14 09:19:37 66853440 20250314/jid1/refiminputs/Roman_TDS_simple_model_F184_322_3_lite_reformatted.fits 2025-03-14 09:19:49 66853440 20250314/jid1/refiminputs/Roman_TDS_simple_model_F184_322_3_lite_reformatted_unc.fits 2025-03-14 09:19:40 66853440 20250314/jid1/refiminputs/Roman_TDS_simple_model_F184_327_14_lite_reformatted.fits 2025-03-14 09:19:53 66853440 20250314/jid1/refiminputs/Roman_TDS_simple_model_F184_327_14_lite_reformatted_unc.fits 2025-03-14 09:19:36 66853440 20250314/jid1/refiminputs/Roman_TDS_simple_model_F184_327_15_lite_reformatted.fits 2025-03-14 09:19:48 66853440 20250314/jid1/refiminputs/Roman_TDS_simple_model_F184_327_15_lite_reformatted_unc.fits 2025-03-14 09:19:31 66853440 20250314/jid1/refiminputs/Roman_TDS_simple_model_F184_702_8_lite_reformatted.fits 2025-03-14 09:19:44 66853440 20250314/jid1/refiminputs/Roman_TDS_simple_model_F184_702_8_lite_reformatted_unc.fits 2025-03-14 09:19:32 66853440 20250314/jid1/refiminputs/Roman_TDS_simple_model_F184_707_1_lite_reformatted.fits 2025-03-14 09:19:45 66853440 20250314/jid1/refiminputs/Roman_TDS_simple_model_F184_707_1_lite_reformatted_unc.fits 2025-03-14 09:19:57 682 20250314/jid1/refiminputs/refimage_sci_inputs.txt 2025-03-14 09:19:57 730 20250314/jid1/refiminputs/refimage_unc_inputs.txt 2025-03-14 11:28:32 66890880 20250314/jid1/scorrimage_masked.fits The general scheme for how the output files are organized in the S3 buckets is according to processing date (Pacific Time) and the associated job ID. The same job ID can exist under different processing dates if reprocessing occurred on different dates (reprocessing on the same date will overwrite products). The files under ``refiminputs`` are only written if the ``upload_inputs`` flag in the software is set to True. These are for off-line analysis and rerunning awaicgen for experimental and tuning purposes. The reference-image products from ``awaicgen`` are initially given generic filenames in these buckets, and, later, will be renamed to filenames like: .. code-block:: rapid_field1234567_fid7_ppid15_v2_rfid12394758_refimage.fits rapid_field1234567_fid7_ppid15_v2_rfid12394758_covmap.fits The above filenames are created after these products are registered in the RAPID pipeline operations database. The products are then copied to a more permanent location (and ultimately archived in MAST). The ``ppid`` gives the pipeline number that generated the reference image, which could be either the difference-image pipeline (``ppid=15``) or a dedicated reference-image pipeline (``ppid=12``). Download and examine log file: .. code-block:: aws s3 cp s3://rapid-pipeline-logs/20250314/rapid_pipeline_job_20250314_jid1_log.txt rapid_pipeline_job_20250314_jid1_log.txt cat rapid_pipeline_job_20250314_jid1_log.txt Last modified: Tue 2026 Jun 16 8:48 a.m.