Category Archives: Uncategorized

LAS Writer

I wrote the following program to create a ghost pass from a casing tally … helps shoot the first set of perforations on depth every time, lowers the risk of slamming guns into the wet shoe sub … It’s written in C but you could port it to whatever language you wanted … have a go at it if you want :-)


#include <iostream>
#include <fstream>
#include <cstring>
#include <sstream>
#include <math.h> 

using namespace std;

int main(int argc, char* argv[]){

  int depthCtr = 0;
  int lasLen = 0;
  int bottomMax;
  int topMax;
  float depth;
  float depthNums[1000];
  int depthNumLen = 0;
  string las[50000] ;
  string inputFile = "";
  string outputFile = "";
  string instr = "";

  ifstream depthFile;
  // check to see if the proper amount of args were entered
  if ( argc == 3){
    inputFile = argv[1];
    outputFile = argv[2];
    } 
  else if( argc == 2 ) {

      if ((strcmp(argv[1], "/?") == 0) || (strcmp(argv[1], "-help") == 0) || (strcmp(argv[1], "--help") == 0) ){
        cout << "\nLasCreator (c) Jason Turner 2016\n";
        cout << "[LasCreator.WellCompletions.Com]\n\n";
        cout << "Creates a ASCII Las logging file from a Casing Tally.\n\n";
        cout << "LASCREATOR.EXE [source] [destination] \n\n";
        cout << "source          Specifies the file that contains Casing Collar depths (one depth per line)\n";
        cout << "destination     Specifies the location and name of the new Las file.\n";
        cout << "\n\n";
        cout << "Usage: LasCreator.exe inputfile.txt outputfile.las\n";
        cout << "Alternatly you can enter the requested filenames at the Prompt.\n\n";
        cout << "The depths need to be in descending order with no decimal places or commas, with only one depth per line.\n\n";
        cout << "[Text File Example]\n\n";
        cout << "20001\n";
        cout << "19960\n";
        cout << "19921\n";
        cout << "19882\n";
        cout << "19845\n\n";
        return 0;
      }

    }

  else {
    cout << "LasCreator (c) Jason Turner 2016\n";
    cout << "[LasCreator.WellCompletions.Com]\n\n";
    cout << "[MANUAL ENTRY]\n\n";
    cout << "Enter the name of the Casing tally text file [ex: F:\\tally.txt]:\n";
    getline(cin, inputFile);
    cout << "Enter the name of the Output filename [ex. F:\\somelasfile.las\n";
    getline(cin, outputFile);
    // return 1;
  }

  // ------------------------------------
  // Build LAS File Header
                las[0] = "~Version Information\n";
                las[1] = "VERS.                      2.0: CWLS Log ASCII Standard - VERSION 2.0\n";
                las[2] = "WRAP.                       NO: One line per depth step\n";
                las[3] = "~Well Information Block\n";
                las[4] = "";
                las[5] = "";
                las[6] = "STEP.FT                -1.0000: STEP\n";
                las[7] = "NULL.                -999.2500: NULL VALUE\n";
                las[8] = "COMP.                         : COMPANY\n";
                las[9] = "WELL.                         : WELL\n";
                las[10] = "FLD.                          : FIELD\n";
                las[11] = "LOC.                          : LOCATION\n";
                las[12] = "DATE.                         : LOG DATE\n";
                las[13] = "SECT.                         : SECTION\n";
                las[14] = "SECT.                         : SECTION\n";
                las[15] = "TOWN.                         : TOWNSHIP\n";
                las[16] = "RANG.                         : RANGE\n";
                las[17] = "API.                          : API#\n";  //Mandatory 
                las[18] = "OS.                           : OTHER SERVICES\n";
                las[19] = "PDAT.FT                       : PERMANENT DATUM\n";
                las[20] = "EEL.FT                        : ELEVATION\n";
                las[21] = "LMF.FT                        : LOG MEASURED FROM\n";
                las[22] = "DMF.FT                        : DRILLING MEASURED FROM\n";
                las[23] = "EKB.FT                        : KB\n";
                las[24] = "EDF.FT                        : DF\n";
                las[25] = "EGL.FT                        : GL\n";
                las[26] = "DATE1.                        : DATE1\n";
                las[27] = "RUN1.                         : RUN NUMBER\n";
                las[28] = "TDD1.FT                       : DEPTH DRILLER\n";
                las[29] = "TDL1.FT                       : DEPTH LOGGER\n";
                las[30] = "BLI1.FT                       : BOTTOM LOGGED INTERVAL\n";
                las[31] = "TLI1.FT                       : TOP LOG INTERVAL\n";
                las[32] = "CDD1.IN_FT                    : CASING DRILLER\n";
                las[33] = "CDL1.FT                       : CASING LOGGER\n";
                las[34] = "BS1.IN                        : BIT SIZE\n";
                las[35] = "DFT1.                         : TYPE FLUID IN HOLE\n";
                las[36] = "DFDV1.GM/C3_CP                : DENSITY/VISCOSITY\n";
                las[37] = "DFPL1.C3                      : PH/FLUID LOSS\n";
                las[38] = "MSS1.                         : SOURCE OF SAMPLE\n";
                las[39] = "RMT1.OHHM_DEGF                : RM@MEASURED TEMP\n";
                las[40] = "RMFT1.OHMM_DEGF               : RMF@MEASURED TEMP\n";
                las[41] = "RMCT1.OHMM_DEGF               : RMC@MEASURED TEMP\n";
                las[42] = "RMFS1.                        : SOURCE OF RMF/RMC\n";
                las[43] = "RMBT1.OHMM_DEGF               : RM@BHT\n";
                las[44] = "TCS1.                         : TIME CIRCULATION STOPPED\n";
                las[45] = "TLOB1.                        : TIME LOGGER ON BOTTOM\n";
                las[46] = "BHT1.DEGF                     : MAXIMUM RECORDED TEMPERATURE\n";
                las[47] = "LUN1.                         : EQUIPMENT NUMBER\n";
                las[48] = "LUL1.                         : LOCATION\n";
                las[49] = "ENGI1.                        : RECORDED BY\n";
                las[50] = "WITN1.                        : WITNESSED BY\n";
                las[51] = "~Curve Information Block\n";
                las[52] = "CCL.                         0: Casing Collar Locator\n";
                las[53] = "DEPT.FT            0 000 00 00: Depth\n";
                las[54] = "~Parameter Information Block\n";
                las[55] = "~A  Depth       CCL\n"; 
        lasLen = 56;
        // END of LAS BUILD
        // -------------------------------------------

        // read in the data into an array 

  depthFile.open(inputFile.c_str());
  if(depthFile.is_open()){
    while (depthFile >> depth) {
      depth = round(depth);
      depthNums[depthNumLen] = depth;
      // Look for duplicates
      // Then for ascending
      if(depthNumLen > 0 && depthNums[depthNumLen-1] == depth){
        depthNums[depthNumLen] = depth -1;
      } else if (depthNumLen > 0 && depthNums[depthNumLen-1] < depth){
        cout << depth;
        cout << "\n\nDepths must be in descending order.\n";
        cout << "Depth number " << depthNumLen << " is incorrect.\n";
        cout << "Depth " << depthNums[depthNumLen-1] << " < " << depth <<"\n\n";
        return 0; 
      }

      // print it out to test it
      cout << depthNums[depthNumLen] << "\n";

      depthNumLen++;

    }
    depthFile.close();
    cout << "\nA total of " << depthNumLen << " Joints found\n";// print out the number of casing joints (depthNumLen)

    // wait for user input to itterate and build the file 
    cout << "Press enter to continue ..."; 
      cin.get();
  }   else { 
    cout << "Unable to open file\n";
    cout << "Check that you have the directory correct?\n\n";
    return 0;
  }

  // parse the depths
  for (int i = 0; i < depthNumLen; i++) {
    if (i == 0) {
      // firstline in data
      bottomMax = depthNums[i];
      cout << depthNums[i] << ".0     1.0     *---\n"; // comment out for faster output
      stringstream ss;
      ss << depthNums[i] << ".0000     1.0000\n";
      las[lasLen] = ss.str();
      depthCtr = depthNums[i] - 1;
      lasLen++;

    } else {
      // Loop for all the other depths

        while (depthCtr != depthNums[i]) {
          //  cout << depthCtr << ".0     0.0     | |\n";
          stringstream ss;
          ss << depthCtr << ".0000     0.0000\n";
          las[lasLen] = ss.str();
          depthCtr--;
          lasLen++;
        }

        cout << depthNums[i] << ".0     1.0     ---\n";
        stringstream ss;
        ss << depthNums[i] << ".0000     1.0000\n";
        las[lasLen] = ss.str();
        depthCtr--;
        lasLen++;        
    }
  }
  topMax = depthCtr + 1;

  stringstream ssBMax;
  ssBMax << "STRT.FT             " << bottomMax << ".0000: START DEPTH\n";
  las[4] = ssBMax.str();
  stringstream ssSMax;
  ssSMax << "STOP.FT             " << topMax << ".0000: STOP DEPTH\n";
  las[5] = ssSMax.str();

  ofstream lasFile(outputFile.c_str());
  for (int i = 0; i < lasLen; i++) {

    lasFile << las[i];
  }
  lasFile.close();

  cout << "\nStarting depth " << bottomMax << ".0\n";
  cout << "Ending depth " << topMax << ".0\n";
  cout << "File " << outputFile << " was created sucessfully.\n\n\n";

  return 0;
}

Coil Drillouts3

Coil Drillouts Cubed.

When you are milling out plugs there is a tendency to stick with the status quo.. running super think gel sweeps and slugs of chemical.  Then after running these super thick slugs, pulling uphole and doing a “wiper” trip, or “short’ trip.  In reality, it is a waste to use viscosifying chemicals other than just enough FR  (Polyacrylamide -CH2CHCONH2)  to keep the circulation pressure low enough to keep moving without putting too much stress on the coil.

When your trying to get the mill/drill cuttings to transport to surface, a new logic applies;  keep the fluid as thin and turbulent as possible.  FR can’t pick up sand on its own; shear and turbulent action pick up the fine sediment and keep it suspended … same with plug debris.  The thicker you make the circulation fluid the worse the problem becomes – it just extrudes over the top of the sand and debris with no turbulent flow.

Thin out your drilling fluid – stop pumping sweeps.  Circulate fluid while moving slowly downhole, until all the surface returns are clean.  Instead of pulling short trips and getting wedged into debris, move downward slowly and let the well clean up just like you were drilling openhole.  When you reach the desired total depth, circulate clean again with about 300 ft/min or more annular velocity.  If you can get more annular velocity go for it.

SPE-187337-MS details the whole procedure needed to overhaul your current drillout program. It’s titled “Stop, Drop and Circulate; An Engineered Approach to Coiled Tubing Drillouts”  {It’s a reference to a popular 1980’s ‘clothing on fire; what to do’ campaign giving advise to ‘Stop, Drop, and Roll’}

(*Note :  The way that the well was stimulated will determine the rate of return you want.  If you flow back too aggressively after a crosslinked gel stimulation the small aperture of the perforations can cause washing out or pitting of the coil downhole.  Huge 100 mesh sand slickwater stimulation’s tend to leave large, tremendously eroded perforations behind that don’t tend to have the harmful velocities seen with small perforations.  If you get to greedy, you can end up causing coil damage.  With slickwater stimulation there is a much larger window… we really haven’t found out what you can get away with, but its a lot…)

The other thing to keep in mind is the size of the flowcross that you are using.  If you have to go cheap and get 2″ valves off the main bore, you run the risk of too much velocity across the coil tubing when the sand laden fluid erodes in transit through the orifice as it enters the 2″ ID of the flowcross.  Always try to get at least 1.5 x the diameter of the coil string for your flowcross when you drill out.  Use valves with a full bore opening when possible.

Drawing Diagrams for Sense of Scale

If you find yourself in a situation where you have to get tools unstuck, or you are fishing a downhole assembly, a 1:1 scale drawing can really help to add perspective to what the situation is.  Using Google SketchUp or other programs. draw a 1:1 scale representation and print it out – you will surely find it helpful.

Here you can see where a 4-5/8″ Bit is inside of 5-1/2″ 20.0# Casing.  Notice that the bit is almost exactly the size of the casing drift.  Additionally seeing the comparison of the size of the motor (3-1/8″) and Tubing (2-3/8″) against the size of the bit is helpful.

It’s also a good idea if you will be using impression blocks,  to cut out the shapes (diameters) of the strings downhole so that you can match them up when you retrieve the impression block, and apply them against the face to see if there is a match.