diff --git a/noche/headers/header_base_v1.ini b/noche/headers/header_base_v1.ini
index 7e770eabd192bed880f889997ebe039d29f5f19d..90ba1e930e8b9769801403450c327ea432680b97 100644
--- a/noche/headers/header_base_v1.ini
+++ b/noche/headers/header_base_v1.ini
@@ -47,6 +47,7 @@ OBSTYPE =             | Observation type
 [Detector]          
 DETECTOR =            | Detector identifier
 DETSIZE =             | [px] Physical CCD dimensions
+DETROT =              | [deg] Rotation offset of the detector
 XPIXSZ =              | [um] Pixel X axis size
 YPIXSZ =              | [um] Pixel Y axis size
 PIXSCALE =            | [arcsec/px] Plate scale in binning 1
diff --git a/noche/noche.py b/noche/noche.py
index 0ab931d68273cd5c4378a3845d562bd1559acbf7..482feb41905292c3dbe7d9fd239cde4b9fe58a3d 100644
--- a/noche/noche.py
+++ b/noche/noche.py
@@ -2,6 +2,7 @@ import configparser
 from pathlib import Path
 from configparser import DuplicateOptionError
 from ast import literal_eval
+import sys
 
 import numpy as np
 from astropy.coordinates import SkyCoord, EarthLocation
@@ -44,10 +45,12 @@ class Noche:
         header_template_path_ini : str
             Path to the configuration file containing the base header.
         """
-
+        
         if debug:
             log.setLevel('DEBUG')
-
+            
+        log.debug(sys._getframe().f_code.co_name)
+            
         self._coord = None
         self._location = None
         self._obstime = None
@@ -69,8 +72,11 @@ class Noche:
         Returns
         -------
         list of str
-            Names of available observatory configuration files (without .ini extension).
+            Names of available observatory configuration files
+            (without .ini extension).
         """
+        log.debug(sys._getframe().f_code.co_name)
+
         data_dir = Path(__file__).parent / self._obs_dir
         return [f.stem for f in data_dir.glob("*.ini")]
 
@@ -84,6 +90,7 @@ class Noche:
         path : str
             Configuration file in .ini format
         """
+        log.debug(sys._getframe().f_code.co_name)
         
         if not path:
             path = Path(__file__).parent / self._head_dir / "header_base_v1.ini"
@@ -117,11 +124,11 @@ class Noche:
         name : str
             One of the supported observatories.
         """
+        log.debug(sys._getframe().f_code.co_name)
 
         data_dir = Path(__file__).parent / self._obs_dir
         ini_path = data_dir / f"{name}.ini"
 
-        log.debug(ini_path)
         if not ini_path.exists():
             msg = f"Observatory config '{ini_path}' not found."
             # raise FileNotFoundError(msg)
@@ -141,6 +148,7 @@ class Noche:
         path : str
             Configuration file in .ini format.
         """
+        log.debug(sys._getframe().f_code.co_name)
 
         config = self._load_config(path)        
 
@@ -156,68 +164,105 @@ class Noche:
             if k in self.header:
                 self.header[k] = val
 
-        #self.header["DETSIZE"] = f'[1:{self.header["NAXIS1"]},1:{self.header["NAXIS2"]}]'
-
         if fits_file:
             self.fill_from_fits_file(path, fits_file)
-
-        self._update()
+        else:
+            self._update()
 
 
+    
     def fill_from_fits_file(self, path=None, fits_file=None):
         """
         Load relevant header info from a fits file of the specific observatory.
-
-         - [Mapping] section defines how the new keywords are related
-           to the old ones.
-           For example: FOCUSPOS = TELFOCUS
-
-         - [Formula] section defines the formula to apply to a header
-           value to match the specifics of the new one.
-           For example: FOCUSPOS = (x)/1000 # Transforming mm in um.
-
+    
+         - [Mapping] defines how the new keywords are related to the old ones.
+         - [Formula] defines formulas to apply *before* generating derived keywords.
+         - [Tweak] defines formulas to apply *after* generating all keywords.
+    
         Parameters
         ----------
         path : str
             Configuration file in .ini format.
         fits_file : str
-            FITS file position.
-
+            FITS file path.
         """
+        log.debug(sys._getframe().f_code.co_name)
 
-        config = self._load_config(path)        
-
+        config = self._load_config(path)
         filename = Path(fits_file)
         self.load_fits(filename)
         fits_file_header = self.hdu.header
-
-        sections = config.sections()
-
+    
+        # Load formulas (if sections exist)
+        pre_formulas = dict(config["Formula"]) if "Formula" in config else {}
+        post_formulas = dict(config["Tweak"]) if "Tweak" in config else {}
+    
+        # Apply Mapping + PreFormula
         loc = config["Mapping"]
         for k in loc.keys():
+
+            if not (k in self.header):
+                log.error(f"{k} not in header")
+                continue
+            
             fits_keyword = loc[k]
             fits_value = fits_file_header[fits_keyword]
             val = self._parse(fits_value)
             self.header[k] = val
             log.info(f"{k:<8} : {val}")
-
-        loc = config["Formula"]
-        for k in loc.keys():
-            fits_formula = loc[k]
-            x = self.header[k]
-            self.header[k] = eval(fits_formula)
-            log.info(f"{k:<8} : from {x} to {self.header[k]}")
-            del x
-
+    
+            if k in pre_formulas:
+                x = self.header[k]
+                try:
+                    self.header[k] = eval(pre_formulas[k])
+                    log.warning(f"{k:<8} (Pre): from {x} to {self.header[k]}")
+                except Exception as e:
+                    log.error(f"Failed to evaluate PreFormula for {k}: {e}")
+        # # Apply Mapping
+        # loc = config["Mapping"]
+        # for k in loc.keys():
+
+        #     if not (k in self.header):
+        #         log.error(f"{k} not in header")
+        #         continue
+            
+        #     fits_keyword = loc[k]
+        #     fits_value = fits_file_header[fits_keyword]
+        #     val = self._parse(fits_value)
+        #     self.header[k] = val
+        #     log.info(f"{k:<8} : {val}")
+            
+        # # Apply PreFormula    
+        # for k, formula in pre_formulas.items():
+        #     if k in self.header:
+        #         x = self.header[k]
+        #         try:
+        #             self.header[k] = eval(formula)
+        #             log.warning(f"{k:<8} (Pre): from {x} to {self.header[k]}")
+        #         except Exception as e:
+        #             log.error(f"Failed to evaluate PreFormula for {k}: {e}")
+        #     else:
+        #         log.debug(f"PreFormula skipped: {k} not in header")
+    
+        # Set coordinates (calls _update(), which triggers set_wcs and others)
         self.set_coordinates(self.header["RA"],
                              self.header["DEC"],
                              obstime=self.header["DATE-OBS"])
-            
-        self._update()
-
+        
+        # Apply PostFormula
+        for k, formula in post_formulas.items():
+            if k in self.header:
+                x = self.header[k]
+                try:
+                    self.header[k] = eval(formula)
+                    log.warning(f"{k:<8} (Post): from {x} to {self.header[k]}")
+                except Exception as e:
+                    log.error(f"Failed to evaluate PostFormula for {k}: {e}")
+            else:
+                log.warning(f"PostFormula skipped: {k} not in header")
+    
         self.header["FILEORIG"] = filename.name
-
-
+        
     def set_location(self, lon, lat, alt):
         """
         Location of the observatory, Separate so that it is
@@ -232,6 +277,7 @@ class Noche:
         alt : float
             Elevation in meters.
         """
+        log.debug(sys._getframe().f_code.co_name)
 
         self._location = EarthLocation(lon, lat, alt)
 
@@ -248,6 +294,7 @@ class Noche:
         obstime : str, astropy.time.Time
             Time of the observation.
         """
+        log.debug(sys._getframe().f_code.co_name)
 
         time = Time(obstime)
         self._obstime = time
@@ -259,7 +306,7 @@ class Noche:
         self.header['DATE-OBS'] = time.isot
         self.header['MJD-OBS'] = time.mjd
 
-        self._update()
+        #self._update()
 
 
     def set_object(self, objname, update_coord=False, obstime=None):
@@ -275,16 +322,17 @@ class Noche:
         obstime : str or astropy.time.Time, optional
             Observation time to associate with coordinates.
         """
+        log.debug(sys._getframe().f_code.co_name)
+
+        if obstime:
+            time = Time(obstime)
+            self.set_obstime(time)
 
         if update_coord:
             try:
                 coord = SkyCoord.from_name(objname)
                 self._coord = coord
 
-                if obstime:
-                    time = Time(obstime)
-                    self.set_obstime(time)
-
                 log.info("Found catalog name")
                 coorstr = coord.to_string(style='hmsdms', sep=' ', precision=1, pad=True)
                 log.info(f"Corresponds to {coorstr}")
@@ -315,6 +363,7 @@ class Noche:
         obstime : str or astropy.time.Time, optional
             Observation time.
         """
+        log.debug(sys._getframe().f_code.co_name)
 
         coord = SkyCoord(ra=ra, dec=dec, unit=(u.hourangle, u.deg))
         self._coord = coord
@@ -325,8 +374,8 @@ class Noche:
 
         self.header['RA'] = coord.ra.to_string(unit=u.hourangle, sep=':',
                                                pad=True, precision=1)
-        self.header['DEC'] = coord.dec.to_string(unit=u.deg, sep=':', pad=True,
-                                                 precision=1)
+        self.header['DEC'] = coord.dec.to_string(unit=u.deg, sep=':',
+                                                 pad=True, precision=1)
         self.header['RA_DEG'] = coord.ra.deg
         self.header['DEC_DEG'] = coord.dec.deg
 
@@ -342,6 +391,7 @@ class Noche:
         ValueError
             If observation time or location is not set.
         """
+        log.debug(sys._getframe().f_code.co_name)
 
         if self._obstime == None or self._location == None:
             raise ValueError("Observation Time, Instrument parameters must be set.")
@@ -365,11 +415,11 @@ class Noche:
 
         # Position angle: with respect to Celestial North Pole
         north_celestial = SkyCoord(ra=0*u.deg, dec=90*u.deg, frame='icrs')
-        posang = self._coord.position_angle(north_celestial).to(u.deg).value
-        self.header['POSANGLE'] = round(posang, 2)
+        posangle = self._coord.position_angle(north_celestial).to(u.deg).value
+        self.header['POSANGLE'] = round(posangle, 2)
 
         # Parallactic angle:  between local meridian and celestial axis
-        parangle = (posang - altaz.az.deg + 360) % 360
+        parangle = (posangle - altaz.az.deg + 360) % 360
         if parangle > 180:
             parangle -= 360  # Wrap to [-180, 180]
 
@@ -390,11 +440,11 @@ class Noche:
         ValueError
             If coordinates or location are not set.
         """
+        log.debug(sys._getframe().f_code.co_name)
 
         if self._coord == None or self._location == None:
             raise ValueError("Observation Coordinates, Instrument parameters must be set.")
 
-
         detsize = self.header['DETSIZE'].strip('[]')
         x_str, y_str = detsize.split(',')
 
@@ -407,20 +457,22 @@ class Noche:
         cdelt2 = round(self.header["PIXSCALE"]*self.header["YBINNING"]*u.arcsec.to(u.deg), 7)
 
         if not angle:
-            angle = self.header["DEROTANG"]
+            angle = self.header["DEROTANG"] + self.header["DETROT"]
 
         angle = np.deg2rad(angle)
 
         crval_ra = self._coord.ra.deg
         crval_dec = self._coord.dec.deg
 
-        self.header['CRPIX1'] = crpix[0]
+        flip = -1 # East to the left
+        
+        self.header['CRPIX1'] = crpix[0] 
         self.header['CRPIX2'] = crpix[1]
         self.header['CRVAL1'] = crval_ra
         self.header['CRVAL2'] = crval_dec
-        self.header['CDELT1'] = cdelt1
+        self.header['CDELT1'] = cdelt1 * flip
         self.header['CDELT2'] = cdelt2
-        self.header["PC1_1"] = +np.cos(angle) *-1 # E to left
+        self.header["PC1_1"] = +np.cos(angle)
         self.header["PC1_2"] = -np.sin(angle)
         self.header["PC2_1"] = +np.sin(angle)
         self.header["PC2_2"] = +np.cos(angle)
@@ -435,6 +487,7 @@ class Noche:
         ValueError
             If coordinates or location are not set.
         """
+        log.debug(sys._getframe().f_code.co_name)
 
         if self._coord == None or self._location == None:
             raise ValueError("Observation Time, Observing location must be set.")
@@ -467,12 +520,14 @@ class Noche:
         """
         List the header keywords that are still empty
         """
+        log.debug(sys._getframe().f_code.co_name)
 
         for k in self.header:
             if self.header[k] == None:
                 print(k, self.header[k])
 
     def load_fits(self, fits_file):
+        log.debug(sys._getframe().f_code.co_name)
 
         filename = fits_file
         hdul = fits.open(filename)
@@ -487,6 +542,7 @@ class Noche:
 
     @staticmethod
     def _load_config(path):
+        log.debug(sys._getframe().f_code.co_name)
                 
         config = configparser.ConfigParser(inline_comment_prefixes=('#',))
 
@@ -504,8 +560,10 @@ class Noche:
         If coordinates, observation and location are provided, then
         additional keywords can be filled
         """
+        log.debug(sys._getframe().f_code.co_name)
 
         if self._coord != None and self._obstime != None and self._location != None:
+
             self.set_altaz_and_parallactic()
             self.set_ambient()
             self.set_wcs()
@@ -525,6 +583,7 @@ class Noche:
         int, float, bool, or str
             Parsed value.
         """
+        # log.debug(sys._getframe().f_code.co_name)
 
         try:
             val = val.strip()
diff --git a/noche/observatories/abobservatory.ini b/noche/observatories/abobservatory.ini
index 72ef2bced39ca8ffc88aaaacaf2116eaaa443126..3bd9992d1fb5d93bf8ee6fea8bb173a7d6637ec3 100644
--- a/noche/observatories/abobservatory.ini
+++ b/noche/observatories/abobservatory.ini
@@ -5,14 +5,14 @@ FOCALLEN = 1170                   # [mm] Telescope focal length
 OBS-LONG = -11.2430135            # [deg] Observatory longitude (East > 0)  
 OBS-LAT = 43.5235203              # [deg] Observatory latitude (North > 0)  
 OBS-ELEV = 1025                   # [m] Observatory altitude above sea level
-DEROTANG = 0                      # [deg] Rotator angle, if any
 INSTRUME = ABOb instrument        # Instrument name
 OBSTYPE = Imaging                 # Observation type
 DETECTOR = Atik 383 L             # Detector identifier
 DETSIZE = [1:3354,1:2529]         # [px] [1:x,1:y] Physical CCD dimensions
+DETROT = -89.67                   # [deg] Rotation offset of the detector
 XPIXSZ = 5.4                      # [um] Pixel X axis size
 YPIXSZ = 5.4                      # [um] Pixel Y axis size
-PIXSCALE = 36                     # [arcsec/px] Plate scale in binning 1
+PIXSCALE = 1.0                      # [arcsec/px] Plate scale in binning 1
 GAIN =                            # [e-/ADU] Gain
 RDNOISE =                         # [e- RMS] Readout noise
 
@@ -38,3 +38,6 @@ SWCREATE = SWCREATE               # Software that created FILEORIG
 
 [Formula]
 
+
+[Tweak]
+CDELT2 = -1*x
diff --git a/noche/observatories/grt.ini b/noche/observatories/grt.ini
index 3f9216819f38a560fef7e6a588c607a09e1e8947..09e0df83e82e26e420ec360563697556ef6a53d4 100644
--- a/noche/observatories/grt.ini
+++ b/noche/observatories/grt.ini
@@ -5,11 +5,11 @@ FOCALLEN = 1520                   # [mm] Telescope focal length
 OBS-LONG = 14.020563              # [deg] Observatory longitude (East > 0)  
 OBS-LAT =  37.9391183             # [deg] Observatory latitude (North > 0)  
 OBS-ELEV = 606                    # [m] Observatory altitude above sea level
-DEROTANG = 0                      # [deg] Rotator angle, if any
 INSTRUME = GRT instrument         # Instrument name
 OBSTYPE = Imaging                 # Observation type
 DETECTOR = Moravian CMOS C4-16000 # Detector identifier
 DETSIZE = [1:4096,1:4096]         # [px] [1:x,1:y] Physical CCD dimensions
+DETROT = +5.0                     # [deg] Rotation offset of the detector
 XPIXSZ = 9                        # [um] Pixel X axis size
 YPIXSZ = 9                        # [um] Pixel Y axis size
 PIXSCALE = 1.22                   # [arcsec/px] Plate scale in binning 1
@@ -37,3 +37,8 @@ YBINNING = YBINNING               # Binning factor in Y
 SWCREATE = SWCREATE               # Software that created FILEORIG
 
 [Formula]
+
+[Tweak]
+CDELT2 = -1*x
+CRPIX1 = x+134
+CRPIX2 = x-500
diff --git a/noche/observatories/oarpaf.ini b/noche/observatories/oarpaf.ini
index c9870feb39c6c6241ec206d73cade7b3fd6d1c6e..1b69ab8a5622e3000944969d6f1e088af2fd02ea 100644
--- a/noche/observatories/oarpaf.ini
+++ b/noche/observatories/oarpaf.ini
@@ -5,11 +5,11 @@ FOCALLEN = 6400                   # [mm] Telescope focal length
 OBS-LONG = 9.2034                 # [deg] Observatory longitude (East > 0)  
 OBS-LAT = 44.5912                 # [deg] Observatory latitude (North > 0)  
 OBS-ELEV = 1469                   # [m] Observatory altitude above sea level
-DEROTANG = -89.67                 # [deg] Rotator angle, if any
 INSTRUME = Cerbero                # Instrument name
 OBSTYPE = Imaging                 # Observation type
 DETECTOR = SBIG STX-16081         # Detector identifier
 DETSIZE = [1:4144,1:4126]         # [px] [1:x,1:y] Physical CCD dimensions
+DETROT = -89.67                   # [deg] Rotation offset of the detector
 XPIXSZ = 9                        # [um] Pixel X axis size
 YPIXSZ = 9                        # [um] Pixel Y axis size
 PIXSCALE = 0.283                  # [arcsec/px] Plate scale in binning 1
@@ -37,4 +37,8 @@ TEMPERAT = HIERARCH CAM AMBIENT   # [C] Ambient temperature
 SWCREATE = SWCREATE               # Software that created FILEORIG
 
 [Formula]
-RA = (x)/15
+RA = x/15
+
+[Tweak]
+CRPIX1 = x+234
+CRPIX2 = x-100
diff --git a/noche/observatories/ogg.ini b/noche/observatories/ogg.ini
index 0e3b4bbed9517c3baf4709d9f07eafec16612ef1..8fc94bb9aa0faa8aac735b61baa61dbd202fdd7a 100644
--- a/noche/observatories/ogg.ini
+++ b/noche/observatories/ogg.ini
@@ -6,13 +6,13 @@ OBS-LONG = 16.9                   # [deg] Observatory longitude (East > 0)
 OBS-LAT = 38.29                   # [deg] Observatory latitude (North > 0)  
 OBS-ELEV = 456                    # [m] Observatory altitude above sea level
 INSTRUME = OGG obs instrument     # Instrument name
-DEROTANG = 0                      # [deg] Rotator angle, if any
 OBSTYPE = Imaging                 # Observation type
 DETECTOR = CMOS QHY268            # Detector identifier
 DETSIZE = [1:6280,1:4210]         # [px] [1:x,1:y] Physical CCD dimensions
+DETROT = 180                      # [deg] Rotation offset of the detector
 XPIXSZ = 3.7                      # [um] Pixel X axis size
 YPIXSZ = 3.7                      # [um] Pixel Y axis size
-PIXSCALE = 4644                   # [arcsec/px] Plate scale in binning 1
+PIXSCALE = 1                      # [arcsec/px] Plate scale in binning 1
 GAIN =                            # [e-/ADU] Gain
 RDNOISE =                         # [e- RMS] Readout noise
 
@@ -37,3 +37,8 @@ TEMPERAT = EXT-TEMP               # [C] Ambient temperature
 SWCREATE = SWCREATE               # Software that created FILEORIG
 
 [Formula]
+
+[Tweak]
+CDELT2 = -1*x
+CRPIX1 = x-400
+CRPIX2 = x+100
diff --git a/noche/observatories/opc.ini b/noche/observatories/opc.ini
index 6de629217c5a8f1801450247045ecbd14445b918..5615e5f01402676dd4eabe4dfac706f5fb5554b3 100644
--- a/noche/observatories/opc.ini
+++ b/noche/observatories/opc.ini
@@ -5,11 +5,11 @@ FOCALLEN = 6400                   # [mm] Telescope focal length
 OBS-LONG = 11.2430135             # [deg] Observatory longitude (East > 0)  
 OBS-LAT = 43.5235203              # [deg] Observatory latitude (North > 0)  
 OBS-ELEV = 450                    # [m] Observatory altitude above sea level
-DEROTANG = -90.0                  # [deg] Rotator angle, if any
 INSTRUME = OPC Instrument         # Instrument name
 OBSTYPE = Imaging                 # Observation type
 DETECTOR = Moravian G4 - KAF09000 # Detector identifier
 DETSIZE = [1:4144,1:4126]         # [px] [1:x,1:y] Physical CCD dimensions
+DETROT = +0.0                     # [deg] Rotation offset of the detector
 XPIXSZ = 12                       # [um] Pixel X axis size
 YPIXSZ = 12                       # [um] Pixel Y axis size
 PIXSCALE = 0.38                   # [arcsec/px] Plate scale in binning 1
@@ -21,8 +21,8 @@ NAXIS1 = NAXIS1                   # [px] X Dimensions of detector
 NAXIS2 = NAXIS2                   # [px] Y dimension of detector
 # OBSERVER =                        # Observer name
 OBJECT   = OBJECT                 # Name of observed object
-RA = RA                           # In sexagesimal or decimal format
-DEC = DEC                         # In sexagesimal or decimal format
+RA = RA_OBJ                           # In sexagesimal or decimal format
+DEC = DEC_OBJ                         # In sexagesimal or decimal format
 DATE-OBS = DATE-OBS               # [YYYY-MM-DDTHH:MM:SS] UTC observation date
 FOCUSTEM = FOCUSTEM               # [C] Focuser temperature
 FOCUSPOS = FOCUSPOS               # [um] Focuser position
@@ -37,4 +37,6 @@ YBINNING = YBINNING               # Binning factor in Y
 SWCREATE = SWCREATE               # Software that created FILEORIG
 
 [Formula]
-RA = (x)/15
+#RA = (x)/15
+
+[Tweak]
diff --git a/noche/observatories/ossfoligno.ini b/noche/observatories/ossfoligno.ini
index 9920a998b35f5f58d39311c8d5d559d133a16fff..51b45fad7519b2f5caeb294a68cb6eff20f9b50c 100644
--- a/noche/observatories/ossfoligno.ini
+++ b/noche/observatories/ossfoligno.ini
@@ -5,7 +5,6 @@ FOCALLEN = 1950                   # [mm] Telescope focal length
 OBS-LONG = -11.2430135            # [deg] Observatory longitude (East > 0)  
 OBS-LAT = 43.5235203              # [deg] Observatory latitude (North > 0)  
 OBS-ELEV = 1025                   # [m] Observatory altitude above sea level
-DEROTANG = 0                      # [deg] Rotator angle, if any
 INSTRUME = Foligno instrument     # Instrument name
 OBSTYPE = Imaging                 # Observation type
 DETECTOR = QHY174MM               # Detector identifier
@@ -37,3 +36,6 @@ TEMPERAT = AOCAMBT                # [C] Ambient temperature
 SWCREATE = SWCREATE               # Software that created FILEORIG
 
 [Formula]
+
+
+[Tweak]